@evident-ai/runner-cdk 0.1.1-dev.04f2155 → 0.1.1-dev.15755a4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -112,7 +112,7 @@ the construct's own dogfooding consumer.
112
112
 
113
113
  This construct never builds an image. Pass any `ecs.ContainerImage` — from a registry, or
114
114
  built from a `Dockerfile` you control. The generic runner image lives separately in
115
- `packages/runner-image`, so you can adopt the image, the construct, or both.
115
+ `runner/docker-images/fargate`, so you can adopt the image, the construct, or both.
116
116
 
117
117
  ## The MicroVM image
118
118
 
@@ -101,7 +101,7 @@ class EvidentScaleToZeroConstruct extends constructs_1.Construct {
101
101
  // --endpoint / --tunnel). The agent is resolved from EVIDENT_AGENT_KEY.
102
102
  EVIDENT_API_URL: evidentApiUrl,
103
103
  EVIDENT_TUNNEL_URL: evidentTunnelUrl,
104
- // Litestream replica target (read by packages/runner-synchroniser, which
104
+ // Litestream replica target (read by runner/synchroniser, which
105
105
  // generates /etc/evident/litestream.yml at boot).
106
106
  LITESTREAM_BUCKET: replicaBucket.bucketName,
107
107
  LITESTREAM_PREFIX: this.replicaPrefix,
@@ -1,9 +1,8 @@
1
1
  "use strict";
2
2
  // Shared literals for the MicroVM controller and for the image it launches.
3
3
  // Every module imports from here rather than restating a value that must match
4
- // across them including `microvm/image/hook-server.ts`, which runs inside the
5
- // image and is esbuild-bundled into the published build context by
6
- // `scripts/build.ts`, so these values reach the image as inlined constants.
4
+ // across them. The image template pins matching copies, guarded by
5
+ // `microvm/image/dockerfile.test.ts`.
7
6
  Object.defineProperty(exports, "__esModule", { value: true });
8
7
  exports.MICROVM_MAX_RUN_SECONDS = exports.SUSPENDING_POLL_INTERVAL_MS = exports.SUSPENDING_POLL_ATTEMPTS = exports.RUN_HOOK_PAYLOAD_MAX_BYTES = exports.HOOK_TIMEOUT_SECONDS = exports.HOOKS_DIR = exports.HOOKS_PORT = void 0;
9
8
  // The port the image's hook server binds, baked into the published Dockerfile
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.handleDoorbell = handleDoorbell;
4
4
  const node_crypto_1 = require("node:crypto");
5
- const webhook_signature_1 = require("@evident/webhook-signature");
5
+ const sdk_1 = require("@evident/sdk");
6
6
  const constants_1 = require("../constants");
7
7
  const doorbell_1 = require("./doorbell");
8
8
  const throttle_retry_1 = require("./throttle-retry");
@@ -175,7 +175,7 @@ async function shouldRecreateForNewerImage(doorbell, shape, runningVersion, micr
175
175
  return compareImageVersions(running, latest) < 0;
176
176
  }
177
177
  async function handleDoorbell({ rawBody, signatureHeader, doorbellSecret, shapes, microvm, sleep, random, }) {
178
- if (!(0, webhook_signature_1.verifyWakeSignature)(rawBody, signatureHeader, doorbellSecret)) {
178
+ if (!(0, sdk_1.verifyEvidentSignature)(rawBody, signatureHeader, doorbellSecret)) {
179
179
  return decide({
180
180
  statusCode: 401,
181
181
  action: 'rejected',
@@ -49,7 +49,7 @@ export interface MicrovmClient {
49
49
  * (docs/spikes/lambda-microvms-phase0/README.md). AWS's own Claude-agents
50
50
  * guidance recommending `maxIdleDurationSeconds: 120` targets VMs reached
51
51
  * inbound and does not apply here. Idle is instead decided IN the VM by
52
- * `evident run --idle-timeout` (packages/runner-cdk/microvm-image/hooks/common.sh's
52
+ * `evident run --idle-timeout` (runner/docker-images/microvm/hooks/common.sh's
53
53
  * `IDLE_TIMEOUT_SECONDS`), whose clean exit drives this
54
54
  * client's own `suspend()` via the `runner.suspend_requested` doorbell.
55
55
  */
@@ -204,9 +204,12 @@ RUN git reset --quiet
204
204
  # database stay per-VM (see entrypoint.sh's pre-warm in evident-runner).
205
205
  RUN if [ -f pnpm-lock.yaml ]; then \
206
206
  pnpm install --frozen-lockfile \
207
- && pnpm run build --filter='./packages/*'; \
207
+ && pnpm run build --filter='./packages/*' \
208
+ --filter='./aws/runner-cdk' \
209
+ --filter='./aws/lambda-microvm-cdk' \
210
+ --filter='./aws/lambda-microvm-runtime'; \
208
211
  else \
209
- echo "[workspace-prep] no pnpm-lock.yaml in the baked repository — skipping the dependency install and the packages build; the agent installs on first use."; \
212
+ echo "[workspace-prep] no pnpm-lock.yaml in the baked repository — skipping the dependency install and the workspace build; the agent installs on first use."; \
210
213
  fi
211
214
 
212
215
  # Data dir for the local dev Postgres cluster; listens on 5433 to match this
@@ -275,14 +275,10 @@ var require_dist = __commonJS({
275
275
  }
276
276
  });
277
277
 
278
- // src/microvm/image/hook-server.ts
278
+ // ../../runner/docker-images/microvm/hook-server.ts
279
279
  var import_lambda_microvm_runtime = __toESM(require_dist());
280
-
281
- // src/microvm/constants.ts
282
- var HOOKS_PORT = 8080;
283
280
  var HOOKS_DIR = "/etc/evident/hooks";
284
-
285
- // src/microvm/image/hook-server.ts
281
+ var HOOKS_PORT = 8080;
286
282
  var server = (0, import_lambda_microvm_runtime.createNodeRuntime)({ hooksDir: HOOKS_DIR });
287
283
  var port = Number(process.env.HOOKS_PORT ?? HOOKS_PORT);
288
284
  server.listen(port, "0.0.0.0", () => {
@@ -2,8 +2,8 @@
2
2
  # Sourced by every hook script. Nothing here runs at image build time.
3
3
  #
4
4
  # These hooks are the SECOND shell speaking the runner-synchroniser CLI contract
5
- # (packages/runner-image/entrypoint.sh is the first), so both are held to it by
6
- # packages/runner-synchroniser/src/shell-contract.test.ts — which derives what
5
+ # (runner/docker-images/fargate/entrypoint.sh is the first), so both are held to it by
6
+ # runner/synchroniser/src/shell-contract.test.ts — which derives what
7
7
  # `run_synchroniser` below must handle from the subcommands this shell calls.
8
8
 
9
9
  # Installed from npm by the image (docker/Dockerfile's ARG
@@ -57,7 +57,7 @@ error() { echo "[hook:$(basename "$0")] ERROR: $*" >&2; }
57
57
  # Returns the CLI's own exit code. Domain outcomes (nothing persisted yet, a
58
58
  # corrupt object) are LOGGED and exit 0, the predicates answer "no" with 10, and
59
59
  # `session-db-classify`'s three typed answers are 30 (fatal)/31 (replica
60
- # unusable)/32 (retry) — see `packages/runner-synchroniser/src/cli.ts`'s own
60
+ # unusable)/32 (retry) — see `runner/synchroniser/src/cli.ts`'s own
61
61
  # comment for what each means, not restated here. Any OTHER non-zero status
62
62
  # means the tool itself broke, which is the only case worth an ERROR here —
63
63
  # EXCEPT 124/137 (a `timeout` deadline/SIGKILL) when the caller asked for one:
@@ -171,7 +171,7 @@ timed_synchroniser() {
171
171
  }
172
172
 
173
173
  # Exports what `runner-synchroniser` resolves its object-store location from
174
- # (packages/runner-synchroniser/src/config.ts). It treats either being empty as
174
+ # (runner/synchroniser/src/config.ts). It treats either being empty as
175
175
  # "persistence disabled" and then reports every restore as a WARNING it still
176
176
  # exits 0 for — so an unset value has to be caught HERE, where it can still be
177
177
  # told apart from "the store is simply empty".
@@ -441,7 +441,7 @@ sync_credentials() {
441
441
  # Writes NOTHING to S3 itself; replication back to S3 is started separately by
442
442
  # `start_litestream` (below) from the `run`/`resume` hooks. `ensure_litestream_config`/
443
443
  # `restore_session_db` are the MicroVM side of the same contract
444
- # packages/runner-image/entrypoint.sh's inlined restore already speaks, going
444
+ # runner/docker-images/fargate/entrypoint.sh's inlined restore already speaks, going
445
445
  # through the SAME runner-synchroniser CLI.
446
446
 
447
447
  # Reads the ~30 MB litestream binary into the page cache, in the background, so
@@ -624,7 +624,7 @@ restore_session_db() {
624
624
  return 0
625
625
  }
626
626
 
627
- # #931's exact lesson, one shell over (packages/runner-image/entrypoint.sh):
627
+ # #931's exact lesson, one shell over (runner/docker-images/fargate/entrypoint.sh):
628
628
  # the `|| { ... }` above only catches a non-zero EXIT — an `env` that exits
629
629
  # 0 with an INCOMPLETE contract (a runner-synchroniser version/build skew)
630
630
  # would otherwise abort right here under `set -u` the moment
@@ -681,7 +681,7 @@ restore_session_db() {
681
681
  esac
682
682
 
683
683
  local classify_rc=0
684
- run_synchroniser session-db-classify "${restore_rc}" 1 --on-unusable-replica=leave || classify_rc=$?
684
+ run_synchroniser session-db-classify "${restore_rc}" 1 --on-unusable-replica=leave --fresh-db-fallback || classify_rc=$?
685
685
  case "${classify_rc}" in
686
686
  0) ;; # restored, or no replica yet — the CLI already logged which
687
687
  31)
@@ -691,8 +691,8 @@ restore_session_db() {
691
691
  # half-restored DB, so the marker stays; a 31 is structurally guaranteed
692
692
  # to be a FRESH one, and replicating it starts a new backup chain instead
693
693
  # of leaving this boot with a zero-width backup window. Same reasoning,
694
- # and same one-line change, as packages/runner-image/entrypoint.sh's `31)`.
695
- warn "SESSION-DB-REPLICA-UNUSABLE: booting with a fresh opencode.db and starting a fresh backup chain this boot (see the WARNING above)"
694
+ # and same one-line change, as runner/docker-images/fargate/entrypoint.sh's `31)`.
695
+ warn "SESSION-DB-REPLICA-UNUSABLE: booting with a fresh opencode.db and replicating into the existing prefix this boot (see the WARNING above)"
696
696
  ;;
697
697
  32)
698
698
  # The CLI's own contract for 32 is "re-run litestream restore and ask
@@ -1122,7 +1122,7 @@ flush_session_db() {
1122
1122
  # returned its 200, so it is deliberately outside that arithmetic.
1123
1123
  #
1124
1124
  # EVIDENT_IDLE_TIMEOUT_SECONDS, deliberately the SAME env var name
1125
- # packages/runner-image/entrypoint.sh uses for the ECS runner's own
1125
+ # runner/docker-images/fargate/entrypoint.sh uses for the ECS runner's own
1126
1126
  # idle-timeout flag, so an operator who knows one knows the other. A
1127
1127
  # non-numeric override must never silently DROP the flag — that degrades to
1128
1128
  # an always-on VM burning ~$2.40/day, exactly the bug this closes — so it
@@ -1161,7 +1161,7 @@ start_tunnel() {
1161
1161
  # into a MicroVM, so it is the ONLY way to seed model credentials on a runner
1162
1162
  # that is already up — the S3 credential store is read at /run and /resume,
1163
1163
  # never mid-life. The allow-list stays a single directory, as on ECS
1164
- # (packages/runner-image/entrypoint.sh): the flag is repeatable, but every
1164
+ # (runner/docker-images/fargate/entrypoint.sh): the flag is repeatable, but every
1165
1165
  # extra entry widens what Evident can write into a VM that executes agent
1166
1166
  # code. ${HOME} is set by the image (ENV HOME=/home/runner) and `set -u` makes
1167
1167
  # an unset one abort rather than silently allow-list "/.claude".
@@ -1208,7 +1208,7 @@ CLI_SHUTDOWN_CEILING_SECONDS=32
1208
1208
  # everything else in the hook. 10 s is ~4x the measured shutdown and gives a
1209
1209
  # provable worst case of 10 + the 10 s `suspend` spends in sync_credentials
1210
1210
  # before us = 20 s, inside the ~55 s the in-VM server allows this script
1211
- # (DEFAULT_TIMEOUT_SECONDS, packages/lambda-microvm-runtime/src/runtime.ts),
1211
+ # (DEFAULT_TIMEOUT_SECONDS, aws/lambda-microvm-runtime/src/runtime.ts),
1212
1212
  # itself inside AWS's 60 s (HOOK_TIMEOUT_SECONDS, src/constants.ts) —
1213
1213
  # overrunning that fails the whole lifecycle transition, which is worse than the
1214
1214
  # kill this replaces. The residual cost is a drain longer than 10 s being
@@ -61,7 +61,7 @@ start_litestream
61
61
  # measures in ~2 s (see the waker note in common.sh).
62
62
  #
63
63
  # Safe to leave running past the hook's own exit: the runtime waits on the
64
- # script's `'exit'`, not `'close'` (packages/lambda-microvm-runtime/src/
64
+ # script's `'exit'`, not `'close'` (aws/lambda-microvm-runtime/src/
65
65
  # runtime.ts), so a lingering child never delays the HTTP response. Its stdio
66
66
  # is deliberately NOT redirected — that inherited fd is how the RUNNER-KEY-*
67
67
  # line reaches CloudWatch, which is the whole point of running it at all.
@@ -56,7 +56,7 @@ class EvidentWaker extends constructs_1.Construct {
56
56
  runtime: lambda.Runtime.NODEJS_22_X,
57
57
  // Pre-bundled at PACKAGE build time (`pnpm --filter @evident-ai/runner-cdk
58
58
  // build`, see scripts/build.ts), not at synth time: esbuild inlines
59
- // @evident/webhook-signature's HMAC verifier into
59
+ // @evident/sdk's HMAC verifier into
60
60
  // dist/waker-lambda/handler.js, so neither this package's published npm
61
61
  // artifact (which ships dist/ already built) nor a consuming app needs
62
62
  // that private workspace package, or esbuild, on synth's PATH. Requires
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evident-ai/runner-cdk",
3
- "version": "0.1.1-dev.04f2155",
3
+ "version": "0.1.1-dev.15755a4",
4
4
  "description": "Reusable CDK constructs for an Evident agent runner: a single scale-to-zero Fargate runner (task + service + per-agent self-stop role + waker Lambda), or a per-session AWS Lambda MicroVM that boots on demand and suspends between messages. Instantiate once per agent from your own stack.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -15,14 +15,14 @@
15
15
  ],
16
16
  "scripts": {
17
17
  "build": "pnpm run build-bundled-deps && ts-node scripts/build.ts",
18
- "//build-bundled-deps": "scripts/build.ts esbuild-bundles src/microvm/image/hook-server.ts, which imports @evident-ai/lambda-microvm-runtime by its built `main`. @evident-ai/lambda-microvm-cdk is a workspace:* devDependency whose types resolve through its own dist/, so tsc --project tsconfig.build.json cannot compile src/microvm/{shapes,construct}.ts without it. Chained into `build` rather than left to turbo's `^build` because publish-runner-cdk.yaml and infrastructure/evident-runner's build-runner-cdk-dep invoke `pnpm --filter @evident-ai/runner-cdk build` directly, which bypasses turbo entirely.",
18
+ "//build-bundled-deps": "scripts/build.ts esbuild-bundles runner/docker-images/microvm/hook-server.ts, which imports @evident-ai/lambda-microvm-runtime by its built `main`. @evident-ai/lambda-microvm-cdk is a workspace:* devDependency whose types resolve through its own dist/, so tsc --project tsconfig.build.json cannot compile src/microvm/{shapes,construct}.ts without it. Chained into `build` rather than left to turbo's `^build` because publish-runner-cdk.yaml and infrastructure/evident-runner's build-runner-cdk-dep invoke `pnpm --filter @evident-ai/runner-cdk build` directly, which bypasses turbo entirely.",
19
19
  "build-bundled-deps": "pnpm --filter @evident-ai/lambda-microvm-cdk build && pnpm --filter @evident-ai/lambda-microvm-runtime build",
20
20
  "typecheck": "tsc --noEmit",
21
21
  "test": "node --test --require ts-node/register 'src/**/*.test.ts'",
22
22
  "format": "prettier --write 'src/**/*.ts'",
23
23
  "lint": "eslint 'src/**/*.ts' --max-warnings=0"
24
24
  },
25
- "//peerDependencies": "@evident-ai/lambda-microvm-cdk is a registry range here, never workspace:*: publish-runner-cdk.yaml ships this package with `npm publish`, not `pnpm publish`, so pnpm's workspace-protocol substitution never runs and a workspace: range would reach npm literally, breaking every external install. Enforced by infrastructure/evident-runner/src/runner-cdk-published-surface.test.ts. The matching devDependency is workspace:* so this monorepo's own build compiles against packages/lambda-microvm-cdk's source.",
25
+ "//peerDependencies": "@evident-ai/lambda-microvm-cdk is a registry range here, never workspace:*: publish-runner-cdk.yaml ships this package with `npm publish`, not `pnpm publish`, so pnpm's workspace-protocol substitution never runs and a workspace: range would reach npm literally, breaking every external install. Enforced by src/published-surface.test.ts. The matching devDependency is workspace:* so this monorepo's own build compiles against aws/lambda-microvm-cdk's source.",
26
26
  "peerDependencies": {
27
27
  "@evident-ai/lambda-microvm-cdk": "^0.1.1",
28
28
  "aws-cdk-lib": "^2.240.0",
@@ -34,14 +34,15 @@
34
34
  "@aws-sdk/client-secrets-manager": "^3.682.0",
35
35
  "@evident-ai/lambda-microvm-cdk": "workspace:*",
36
36
  "@evident-ai/lambda-microvm-runtime": "workspace:*",
37
- "@evident/webhook-signature": "workspace:*",
37
+ "@evident/sdk": "workspace:*",
38
38
  "@types/node": "^22",
39
39
  "aws-cdk-lib": "^2.240.0",
40
40
  "constructs": "^10.5.0",
41
41
  "esbuild": "^0.25.2",
42
42
  "prettier": "^3.3.3",
43
43
  "ts-node": "^10.9.2",
44
- "typescript": "^5.6.3"
44
+ "typescript": "^5.6.3",
45
+ "runner-microvm-image": "workspace:*"
45
46
  },
46
47
  "publishConfig": {
47
48
  "access": "public"
@@ -49,7 +50,7 @@
49
50
  "repository": {
50
51
  "type": "git",
51
52
  "url": "https://github.com/sroze/evident.git",
52
- "directory": "packages/runner-cdk"
53
+ "directory": "aws/runner-cdk"
53
54
  },
54
55
  "homepage": "https://evident.run",
55
56
  "author": "Evident <hello@evident.run>",