@vm0/runner 2.8.2 → 2.8.4

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.
Files changed (2) hide show
  1. package/index.js +95 -11
  2. package/package.json +2 -2
package/index.js CHANGED
@@ -27,7 +27,12 @@ var runnerConfigSchema = z.object({
27
27
  vcpu: z.number().int().min(1).default(2),
28
28
  memory_mb: z.number().int().min(128).default(2048),
29
29
  poll_interval_ms: z.number().int().min(1e3).default(5e3)
30
- }).default({}),
30
+ }).default({
31
+ max_concurrent: 1,
32
+ vcpu: 2,
33
+ memory_mb: 2048,
34
+ poll_interval_ms: 5e3
35
+ }),
31
36
  firecracker: z.object({
32
37
  binary: z.string().min(1, "Firecracker binary path is required"),
33
38
  kernel: z.string().min(1, "Kernel path is required"),
@@ -35,7 +40,9 @@ var runnerConfigSchema = z.object({
35
40
  }),
36
41
  proxy: z.object({
37
42
  port: z.number().int().min(1024).max(65535).default(8080)
38
- }).default({})
43
+ }).default({
44
+ port: 8080
45
+ })
39
46
  });
40
47
  var debugConfigSchema = z.object({
41
48
  name: z.string().default("debug-runner"),
@@ -43,13 +50,21 @@ var debugConfigSchema = z.object({
43
50
  server: z.object({
44
51
  url: z.string().url().default("http://localhost:3000"),
45
52
  token: z.string().default("debug-token")
46
- }).default({}),
53
+ }).default({
54
+ url: "http://localhost:3000",
55
+ token: "debug-token"
56
+ }),
47
57
  sandbox: z.object({
48
58
  max_concurrent: z.number().int().min(1).default(1),
49
59
  vcpu: z.number().int().min(1).default(2),
50
60
  memory_mb: z.number().int().min(128).default(2048),
51
61
  poll_interval_ms: z.number().int().min(1e3).default(5e3)
52
- }).default({}),
62
+ }).default({
63
+ max_concurrent: 1,
64
+ vcpu: 2,
65
+ memory_mb: 2048,
66
+ poll_interval_ms: 5e3
67
+ }),
53
68
  firecracker: z.object({
54
69
  binary: z.string().min(1, "Firecracker binary path is required"),
55
70
  kernel: z.string().min(1, "Kernel path is required"),
@@ -57,7 +72,9 @@ var debugConfigSchema = z.object({
57
72
  }),
58
73
  proxy: z.object({
59
74
  port: z.number().int().min(1024).max(65535).default(8080)
60
- }).default({})
75
+ }).default({
76
+ port: 8080
77
+ })
61
78
  });
62
79
  function loadDebugConfig(configPath) {
63
80
  if (!fs.existsSync(configPath)) {
@@ -67,7 +84,7 @@ function loadDebugConfig(configPath) {
67
84
  const raw = yaml.parse(content);
68
85
  const result = debugConfigSchema.safeParse(raw);
69
86
  if (!result.success) {
70
- const errors = result.error.errors.map((e) => ` - ${e.path.join(".")}: ${e.message}`).join("\n");
87
+ const errors = result.error.issues.map((e) => ` - ${e.path.join(".")}: ${e.message}`).join("\n");
71
88
  throw new Error(`Invalid configuration:
72
89
  ${errors}`);
73
90
  }
@@ -81,7 +98,7 @@ function loadConfig(configPath) {
81
98
  const raw = yaml.parse(content);
82
99
  const result = runnerConfigSchema.safeParse(raw);
83
100
  if (!result.success) {
84
- const errors = result.error.errors.map((e) => ` - ${e.path.join(".")}: ${e.message}`).join("\n");
101
+ const errors = result.error.issues.map((e) => ` - ${e.path.join(".")}: ${e.message}`).join("\n");
85
102
  throw new Error(`Invalid configuration:
86
103
  ${errors}`);
87
104
  }
@@ -6362,11 +6379,19 @@ var scheduleResponseSchema = z15.object({
6362
6379
  volumeVersions: z15.record(z15.string(), z15.string()).nullable(),
6363
6380
  enabled: z15.boolean(),
6364
6381
  nextRunAt: z15.string().nullable(),
6365
- lastRunAt: z15.string().nullable(),
6366
- lastRunId: z15.string().nullable(),
6367
6382
  createdAt: z15.string(),
6368
6383
  updatedAt: z15.string()
6369
6384
  });
6385
+ var runSummarySchema = z15.object({
6386
+ id: z15.string().uuid(),
6387
+ status: z15.enum(["pending", "running", "completed", "failed", "timeout"]),
6388
+ createdAt: z15.string(),
6389
+ completedAt: z15.string().nullable(),
6390
+ error: z15.string().nullable()
6391
+ });
6392
+ var scheduleRunsResponseSchema = z15.object({
6393
+ runs: z15.array(runSummarySchema)
6394
+ });
6370
6395
  var scheduleListResponseSchema = z15.object({
6371
6396
  schedules: z15.array(scheduleResponseSchema)
6372
6397
  });
@@ -6495,6 +6520,29 @@ var schedulesEnableContract = c11.router({
6495
6520
  summary: "Disable schedule"
6496
6521
  }
6497
6522
  });
6523
+ var scheduleRunsContract = c11.router({
6524
+ /**
6525
+ * GET /api/agent/schedules/:name/runs
6526
+ * List recent runs for a schedule
6527
+ */
6528
+ listRuns: {
6529
+ method: "GET",
6530
+ path: "/api/agent/schedules/:name/runs",
6531
+ pathParams: z15.object({
6532
+ name: z15.string().min(1, "Schedule name required")
6533
+ }),
6534
+ query: z15.object({
6535
+ composeId: z15.string().uuid("Compose ID required"),
6536
+ limit: z15.coerce.number().min(0).max(100).default(5)
6537
+ }),
6538
+ responses: {
6539
+ 200: scheduleRunsResponseSchema,
6540
+ 401: apiErrorSchema,
6541
+ 404: apiErrorSchema
6542
+ },
6543
+ summary: "List recent runs for a schedule"
6544
+ }
6545
+ });
6498
6546
 
6499
6547
  // ../../packages/core/src/contracts/public/common.ts
6500
6548
  import { z as z16 } from "zod";
@@ -10378,7 +10426,7 @@ function initMetrics(config) {
10378
10426
  url: "https://api.axiom.co/v1/metrics",
10379
10427
  headers: {
10380
10428
  Authorization: `Bearer ${config.axiomToken}`,
10381
- "X-Axiom-Dataset": `runner-metrics-${env}`
10429
+ "X-Axiom-Dataset": `vm0-sandbox-op-log-${env}`
10382
10430
  }
10383
10431
  });
10384
10432
  meterProvider = new MeterProvider({
@@ -10848,6 +10896,42 @@ async function executeJob(context, config, options = {}) {
10848
10896
  completed = true;
10849
10897
  break;
10850
10898
  }
10899
+ if (!options.benchmarkMode) {
10900
+ const processCheck = await ssh.exec(
10901
+ `pgrep -f "env-loader.py" > /dev/null 2>&1 && echo "RUNNING" || echo "DEAD"`
10902
+ );
10903
+ if (processCheck.stdout.trim() === "DEAD") {
10904
+ log(
10905
+ `[Executor] Agent process died unexpectedly without writing exit code`
10906
+ );
10907
+ const logContent = await ssh.exec(
10908
+ `tail -50 ${systemLogFile} 2>/dev/null`
10909
+ );
10910
+ const dmesgCheck = await ssh.exec(
10911
+ `dmesg | tail -20 | grep -iE "killed|oom" 2>/dev/null`
10912
+ );
10913
+ let errorMsg = "Agent process terminated unexpectedly";
10914
+ if (dmesgCheck.stdout.toLowerCase().includes("oom") || dmesgCheck.stdout.toLowerCase().includes("killed")) {
10915
+ errorMsg = "Agent process killed by OOM killer";
10916
+ log(`[Executor] OOM detected: ${dmesgCheck.stdout}`);
10917
+ }
10918
+ if (logContent.stdout) {
10919
+ log(
10920
+ `[Executor] Last log output: ${logContent.stdout.substring(0, 500)}`
10921
+ );
10922
+ }
10923
+ const durationMs2 = Date.now() - startTime;
10924
+ recordRunnerOperation({
10925
+ actionType: "agent_execute",
10926
+ durationMs: durationMs2,
10927
+ success: false
10928
+ });
10929
+ return {
10930
+ exitCode: 1,
10931
+ error: errorMsg
10932
+ };
10933
+ }
10934
+ }
10851
10935
  }
10852
10936
  const durationMs = Date.now() - startTime;
10853
10937
  const duration = Math.round(durationMs / 1e3);
@@ -11247,7 +11331,7 @@ var benchmarkCommand = new Command3("benchmark").description(
11247
11331
  });
11248
11332
 
11249
11333
  // src/index.ts
11250
- var version = true ? "2.8.2" : "0.1.0";
11334
+ var version = true ? "2.8.4" : "0.1.0";
11251
11335
  program.name("vm0-runner").version(version).description("Self-hosted runner for VM0 agents");
11252
11336
  program.addCommand(startCommand);
11253
11337
  program.addCommand(statusCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/runner",
3
- "version": "2.8.2",
3
+ "version": "2.8.4",
4
4
  "description": "Self-hosted runner for VM0 agents",
5
5
  "repository": {
6
6
  "type": "git",
@@ -22,6 +22,6 @@
22
22
  "@opentelemetry/semantic-conventions": "^1.25.0",
23
23
  "commander": "^14.0.0",
24
24
  "yaml": "^2.3.4",
25
- "zod": "^3.25.64"
25
+ "zod": "^4.1.12"
26
26
  }
27
27
  }