self-bench 0.3.3 → 0.3.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 (139) hide show
  1. package/Dockerfile.sandbox +1 -1
  2. package/README.md +20 -0
  3. package/bun.lock +48 -0
  4. package/compose.yaml +7 -1
  5. package/dist/agent-smoke-main.js +3 -2
  6. package/dist/agent-smoke-main.js.map +1 -1
  7. package/dist/agent-smoke.d.ts +2 -1
  8. package/dist/agent-smoke.d.ts.map +1 -1
  9. package/dist/agent-smoke.js +6 -1
  10. package/dist/agent-smoke.js.map +1 -1
  11. package/dist/api.d.ts +24 -0
  12. package/dist/api.d.ts.map +1 -1
  13. package/dist/api.js +25 -18
  14. package/dist/api.js.map +1 -1
  15. package/dist/build-metadata.js +1 -1
  16. package/dist/cli.js +67 -11
  17. package/dist/cli.js.map +1 -1
  18. package/dist/config.d.ts +36 -10
  19. package/dist/config.d.ts.map +1 -1
  20. package/dist/config.js +89 -15
  21. package/dist/config.js.map +1 -1
  22. package/dist/contracts.d.ts +22 -2
  23. package/dist/contracts.d.ts.map +1 -1
  24. package/dist/contracts.js +31 -6
  25. package/dist/contracts.js.map +1 -1
  26. package/dist/eval-main.js +3 -2
  27. package/dist/eval-main.js.map +1 -1
  28. package/dist/evaluate.d.ts +2 -1
  29. package/dist/evaluate.d.ts.map +1 -1
  30. package/dist/evaluate.js +2 -1
  31. package/dist/evaluate.js.map +1 -1
  32. package/dist/harbor-environment.d.ts +2 -0
  33. package/dist/harbor-environment.d.ts.map +1 -0
  34. package/dist/harbor-environment.js +15 -0
  35. package/dist/harbor-environment.js.map +1 -0
  36. package/dist/harbor-results.d.ts.map +1 -1
  37. package/dist/harbor-results.js +2 -0
  38. package/dist/harbor-results.js.map +1 -1
  39. package/dist/process.d.ts +2 -1
  40. package/dist/process.d.ts.map +1 -1
  41. package/dist/process.js.map +1 -1
  42. package/dist/providers.d.ts +8 -0
  43. package/dist/providers.d.ts.map +1 -0
  44. package/dist/providers.js +14 -0
  45. package/dist/providers.js.map +1 -0
  46. package/dist/reaudit-main.js +5 -5
  47. package/dist/reaudit-main.js.map +1 -1
  48. package/dist/repair-main.js +5 -5
  49. package/dist/repair-main.js.map +1 -1
  50. package/dist/sandbox-author.bundle.js +40 -6
  51. package/dist/sandbox-timeout.d.ts +11 -0
  52. package/dist/sandbox-timeout.d.ts.map +1 -0
  53. package/dist/sandbox-timeout.js +41 -0
  54. package/dist/sandbox-timeout.js.map +1 -0
  55. package/dist/sandbox-validation-repair.bundle.js +40 -6
  56. package/dist/sandbox.d.ts +2 -2
  57. package/dist/sandbox.d.ts.map +1 -1
  58. package/dist/sandbox.js +10 -3
  59. package/dist/sandbox.js.map +1 -1
  60. package/dist/temporal/activities.d.ts +2 -2
  61. package/dist/temporal/activities.d.ts.map +1 -1
  62. package/dist/temporal/activities.js +7 -1
  63. package/dist/temporal/activities.js.map +1 -1
  64. package/dist/temporal/worker-main.js +2 -2
  65. package/dist/temporal/worker-main.js.map +1 -1
  66. package/dist/terminal-prompts.d.ts +26 -0
  67. package/dist/terminal-prompts.d.ts.map +1 -0
  68. package/dist/terminal-prompts.js +137 -0
  69. package/dist/terminal-prompts.js.map +1 -0
  70. package/dist/terminal-reporter.d.ts +30 -0
  71. package/dist/terminal-reporter.d.ts.map +1 -0
  72. package/dist/terminal-reporter.js +90 -0
  73. package/dist/terminal-reporter.js.map +1 -0
  74. package/dist/validate-main.js +8 -2
  75. package/dist/validate-main.js.map +1 -1
  76. package/dist/vercel-cli.d.ts +64 -0
  77. package/dist/vercel-cli.d.ts.map +1 -0
  78. package/dist/vercel-cli.js +303 -0
  79. package/dist/vercel-cli.js.map +1 -0
  80. package/dist/vercel-command.d.ts +14 -0
  81. package/dist/vercel-command.d.ts.map +1 -0
  82. package/dist/vercel-command.js +93 -0
  83. package/dist/vercel-command.js.map +1 -0
  84. package/dist/vercel-executor.d.ts +14 -0
  85. package/dist/vercel-executor.d.ts.map +1 -0
  86. package/dist/vercel-executor.js +356 -0
  87. package/dist/vercel-executor.js.map +1 -0
  88. package/dist/vercel-fetch.d.ts +6 -0
  89. package/dist/vercel-fetch.d.ts.map +1 -0
  90. package/dist/vercel-fetch.js +39 -0
  91. package/dist/vercel-fetch.js.map +1 -0
  92. package/dist/vercel-profile.d.ts +34 -0
  93. package/dist/vercel-profile.d.ts.map +1 -0
  94. package/dist/vercel-profile.js +244 -0
  95. package/dist/vercel-profile.js.map +1 -0
  96. package/dist/vercel-runtime-image.d.ts +51 -0
  97. package/dist/vercel-runtime-image.d.ts.map +1 -0
  98. package/dist/vercel-runtime-image.js +123 -0
  99. package/dist/vercel-runtime-image.js.map +1 -0
  100. package/dist/vercel-setup-probe.d.ts +49 -0
  101. package/dist/vercel-setup-probe.d.ts.map +1 -0
  102. package/dist/vercel-setup-probe.js +151 -0
  103. package/dist/vercel-setup-probe.js.map +1 -0
  104. package/dist/vercel-setup.d.ts +42 -0
  105. package/dist/vercel-setup.d.ts.map +1 -0
  106. package/dist/vercel-setup.js +280 -0
  107. package/dist/vercel-setup.js.map +1 -0
  108. package/docs/evaluations.md +2 -0
  109. package/docs/operations.md +128 -6
  110. package/package.json +3 -1
  111. package/src/agent-smoke-main.ts +3 -2
  112. package/src/agent-smoke.ts +8 -2
  113. package/src/api.ts +31 -18
  114. package/src/cli.ts +72 -11
  115. package/src/config.ts +150 -25
  116. package/src/contracts.ts +33 -6
  117. package/src/eval-main.ts +3 -2
  118. package/src/evaluate.ts +5 -3
  119. package/src/harbor-environment.ts +17 -0
  120. package/src/harbor-results.ts +2 -0
  121. package/src/process.ts +3 -1
  122. package/src/providers.ts +22 -0
  123. package/src/reaudit-main.ts +8 -5
  124. package/src/repair-main.ts +8 -5
  125. package/src/sandbox-timeout.ts +56 -0
  126. package/src/sandbox.ts +15 -5
  127. package/src/temporal/activities.ts +9 -3
  128. package/src/temporal/worker-main.ts +2 -2
  129. package/src/terminal-prompts.ts +197 -0
  130. package/src/terminal-reporter.ts +126 -0
  131. package/src/validate-main.ts +9 -3
  132. package/src/vercel-cli.ts +403 -0
  133. package/src/vercel-command.ts +127 -0
  134. package/src/vercel-executor.ts +448 -0
  135. package/src/vercel-fetch.ts +45 -0
  136. package/src/vercel-profile.ts +319 -0
  137. package/src/vercel-runtime-image.ts +204 -0
  138. package/src/vercel-setup-probe.ts +229 -0
  139. package/src/vercel-setup.ts +419 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vercel-setup-probe.js","sourceRoot":"","sources":["../src/vercel-setup-probe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { VercelCredentials } from "./config.js";
2
+ import { type SetupPrompter } from "./terminal-prompts.js";
3
+ import { type SetupReporter } from "./terminal-reporter.js";
4
+ import { type VercelProject, type VercelTeam } from "./vercel-cli.js";
5
+ import { saveVercelProfile, type VercelProfile, type VercelProfileData } from "./vercel-profile.js";
6
+ import { type VercelRuntimeImageCli } from "./vercel-runtime-image.js";
7
+ import { type VercelCapability } from "./vercel-setup-probe.js";
8
+ export interface VercelSetupCli extends VercelRuntimeImageCli {
9
+ ensureAvailable(): Promise<void>;
10
+ ensureLoggedIn(): Promise<void>;
11
+ listTeams(): Promise<readonly VercelTeam[]>;
12
+ listProjects(teamSlug: string): Promise<readonly VercelProject[]>;
13
+ createProject(teamSlug: string, projectName: string): Promise<VercelProject>;
14
+ }
15
+ export interface VercelSetupServices {
16
+ readonly cli: VercelSetupCli;
17
+ readonly prompter: SetupPrompter;
18
+ readonly reporter: SetupReporter;
19
+ readonly interactive: boolean;
20
+ readonly loadProfiles: (directory: string) => Promise<VercelProfileData>;
21
+ readonly saveProfile: typeof saveVercelProfile;
22
+ readonly probe: (input: {
23
+ readonly credentials: VercelCredentials;
24
+ readonly image: string;
25
+ readonly signal?: AbortSignal;
26
+ }) => Promise<VercelCapability>;
27
+ readonly sleep: (delayMs: number) => Promise<void>;
28
+ }
29
+ export interface VercelSetupResult {
30
+ readonly profileName: string;
31
+ readonly profile: VercelProfile;
32
+ readonly configDirectory: string;
33
+ readonly projectCreated: boolean;
34
+ readonly imagePublished: boolean;
35
+ }
36
+ export declare function setupVercel(options?: {
37
+ readonly profileName?: string;
38
+ readonly environment?: NodeJS.ProcessEnv;
39
+ readonly projectRoot?: string;
40
+ readonly verbose?: boolean;
41
+ }, providedServices?: VercelSetupServices): Promise<VercelSetupResult>;
42
+ //# sourceMappingURL=vercel-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vercel-setup.d.ts","sourceRoot":"","sources":["../src/vercel-setup.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,aAAa,EAAyB,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAa,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACjF,OAAO,EAEL,iBAAiB,EAEjB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAEvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGL,KAAK,qBAAqB,EAE3B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAyB,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAKvF,MAAM,WAAW,cAAe,SAAQ,qBAAqB;IAC3D,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,SAAS,IAAI,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC,CAAC;IAC5C,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,aAAa,EAAE,CAAC,CAAC;IAClE,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAC9E;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACzE,QAAQ,CAAC,WAAW,EAAE,OAAO,iBAAiB,CAAC;IAC/C,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE;QACtB,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;QACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;KAC/B,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAED,wBAAsB,WAAW,CAC/B,OAAO,GAAE;IACP,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACzC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CACvB,EACN,gBAAgB,CAAC,EAAE,mBAAmB,GACrC,OAAO,CAAC,iBAAiB,CAAC,CAiJ5B"}
@@ -0,0 +1,280 @@
1
+ import { dirname, resolve } from "node:path";
2
+ import { setTimeout as delay } from "node:timers/promises";
3
+ import { fileURLToPath } from "node:url";
4
+ import { isInteractiveTerminal, SetupCanceledError, TerminalPrompter, } from "./terminal-prompts.js";
5
+ import { TerminalSetupReporter } from "./terminal-reporter.js";
6
+ import { VercelCli } from "./vercel-cli.js";
7
+ import { loadVercelProfileData, saveVercelProfile, selfBenchConfigDirectory, validateVercelProfileName, } from "./vercel-profile.js";
8
+ import { DEFAULT_VCR_REPOSITORY, ensureVercelRuntimeImage, vercelRuntimeFingerprint, } from "./vercel-runtime-image.js";
9
+ import { probeVercelCapability } from "./vercel-setup-probe.js";
10
+ const DEFAULT_PROFILE_NAME = "default";
11
+ const DEFAULT_PROJECT_NAME = "selfbench-sandbox";
12
+ export async function setupVercel(options = {}, providedServices) {
13
+ const services = providedServices ?? defaultServices(options.verbose ?? false);
14
+ if (!services.interactive) {
15
+ throw new Error("self-bench setup vercel requires an interactive terminal; unattended environments should set VERCEL_TOKEN, VERCEL_TEAM_ID, VERCEL_PROJECT_ID, SELFBENCH_VERCEL_IMAGE, and optionally SELFBENCH_VERCEL_TIMEOUT_CAP");
16
+ }
17
+ services.reporter.intro("Configure Vercel Sandbox");
18
+ const profileName = validateVercelProfileName(options.profileName ?? DEFAULT_PROFILE_NAME);
19
+ const environment = options.environment ?? process.env;
20
+ const configDirectory = selfBenchConfigDirectory(environment);
21
+ const projectRoot = resolve(options.projectRoot ?? defaultProjectRoot());
22
+ const existingData = await services.loadProfiles(configDirectory);
23
+ const existingProfile = existingData.profiles[profileName];
24
+ const existingToken = existingData.tokens[profileName];
25
+ const action = await chooseSetupAction(services.prompter, existingProfile, existingToken);
26
+ await services.cli.ensureAvailable();
27
+ await services.cli.ensureLoggedIn();
28
+ const teams = await services.cli.listTeams();
29
+ if (teams.length === 0) {
30
+ throw new Error("The Vercel account has no accessible team or personal scope");
31
+ }
32
+ let selected;
33
+ let projectCreated = false;
34
+ if (action === "change-project" || !existingProfile) {
35
+ const team = await chooseTeam(services.prompter, teams);
36
+ const projectSelection = await chooseProject(services, team);
37
+ selected = { team, project: projectSelection.project };
38
+ projectCreated = projectSelection.created;
39
+ }
40
+ else {
41
+ selected = await resolveExistingSelection(services.cli, teams, existingProfile);
42
+ }
43
+ const fingerprint = await vercelRuntimeFingerprint(projectRoot);
44
+ const imageResult = await ensureVercelRuntimeImage({
45
+ services: {
46
+ cli: services.cli,
47
+ prompter: services.prompter,
48
+ reporter: services.reporter,
49
+ sleep: services.sleep,
50
+ },
51
+ scope: { teamSlug: selected.team.slug, projectId: selected.project.id },
52
+ projectRoot,
53
+ fingerprint,
54
+ preferredRepository: action === "change-project" || !existingProfile
55
+ ? DEFAULT_VCR_REPOSITORY
56
+ : existingProfile.vcrRepository,
57
+ });
58
+ const token = action === "revalidate" && existingToken
59
+ ? existingToken
60
+ : await requestProjectToken(services, selected);
61
+ const credentials = {
62
+ token,
63
+ teamId: selected.team.id,
64
+ projectId: selected.project.id,
65
+ };
66
+ const controller = new AbortController();
67
+ const interrupt = () => controller.abort(new SetupCanceledError());
68
+ process.once("SIGINT", interrupt);
69
+ let capability;
70
+ try {
71
+ capability = await services.reporter.task({
72
+ pending: "Verifying Sandbox access and detecting the timeout cap",
73
+ success: "Sandbox access verified",
74
+ failure: "Sandbox verification failed",
75
+ }, async () => {
76
+ try {
77
+ return await services.probe({
78
+ credentials,
79
+ image: imageResult.image,
80
+ signal: controller.signal,
81
+ });
82
+ }
83
+ catch (error) {
84
+ if (controller.signal.aborted) {
85
+ throw controller.signal.reason;
86
+ }
87
+ throw error;
88
+ }
89
+ });
90
+ }
91
+ catch (error) {
92
+ if (controller.signal.aborted) {
93
+ throw controller.signal.reason;
94
+ }
95
+ throw new Error(`Vercel Sandbox verification failed: ${errorMessage(error)}. If the access token expired or has the wrong project scope, rerun setup and paste a new project-scoped token; choose Replace the access token when revalidating an existing profile.`, { cause: error });
96
+ }
97
+ finally {
98
+ process.removeListener("SIGINT", interrupt);
99
+ }
100
+ if (capability.timeoutClass === "45m") {
101
+ services.reporter.warn("This Vercel scope enforces a 45-minute Sandbox limit. SelfBench will cap longer authoring and repair stages at 45 minutes; accepted tasks remain fully validated, but slow candidates may time out and be rejected.");
102
+ services.reporter.warn("Vercel Hobby usage is intended for personal, non-commercial work. Use a paid team for commercial SelfBench runs.");
103
+ if (!(await services.prompter.confirm("Continue with the 45-minute compatibility cap?", true))) {
104
+ services.reporter.cancel("Vercel setup canceled before profile activation.");
105
+ throw new SetupCanceledError("Vercel setup canceled before profile activation");
106
+ }
107
+ }
108
+ const profile = {
109
+ teamId: selected.team.id,
110
+ teamSlug: selected.team.slug,
111
+ teamName: selected.team.name,
112
+ projectId: selected.project.id,
113
+ projectName: selected.project.name,
114
+ vcrRepository: imageResult.repository,
115
+ image: imageResult.image,
116
+ runtimeFingerprint: fingerprint,
117
+ timeoutCapMs: capability.timeoutCapMs,
118
+ capabilityCheckedAt: capability.checkedAt,
119
+ };
120
+ await services.saveProfile({ directory: configDirectory, profileName, profile, token });
121
+ services.reporter.finish(`Saved Vercel profile "${profileName}"`, [
122
+ `Location: ${configDirectory}`,
123
+ `Project: ${profile.teamSlug}/${profile.projectName}`,
124
+ `Runtime image: ${imageRepository(profile.image)}`,
125
+ "Digest:",
126
+ ` ${imageDigest(profile.image)}`,
127
+ `Vercel tier: ${timeoutTier(capability.timeoutClass)}`,
128
+ `Timeout cap: ${formatDuration(profile.timeoutCapMs)}`,
129
+ "Resources: Project and runtime image remain reusable after self-bench down.",
130
+ ]);
131
+ return {
132
+ profileName,
133
+ profile,
134
+ configDirectory,
135
+ projectCreated,
136
+ imagePublished: imageResult.published,
137
+ };
138
+ }
139
+ function defaultServices(verbose) {
140
+ const reporter = new TerminalSetupReporter({ verbose });
141
+ return {
142
+ cli: new VercelCli(),
143
+ prompter: new TerminalPrompter(),
144
+ reporter,
145
+ interactive: isInteractiveTerminal(),
146
+ loadProfiles: loadVercelProfileData,
147
+ saveProfile: saveVercelProfile,
148
+ probe: probeVercelCapability,
149
+ sleep: async (delayMs) => await delay(delayMs),
150
+ };
151
+ }
152
+ async function chooseSetupAction(prompter, profile, token) {
153
+ if (!profile) {
154
+ return "change-project";
155
+ }
156
+ const choices = [
157
+ ...(token
158
+ ? [
159
+ {
160
+ value: "revalidate",
161
+ label: `Revalidate ${profile.teamSlug}/${profile.projectName}`,
162
+ hint: "Recommended",
163
+ },
164
+ ]
165
+ : []),
166
+ { value: "replace-token", label: "Replace the access token" },
167
+ { value: "change-project", label: "Choose another team or project" },
168
+ ];
169
+ const selected = await prompter.select(`Vercel profile is already configured for ${profile.teamSlug}/${profile.projectName}`, choices, token ? "revalidate" : "replace-token");
170
+ if (selected !== "revalidate" && selected !== "replace-token" && selected !== "change-project") {
171
+ throw new Error(`Unsupported Vercel setup action: ${selected}`);
172
+ }
173
+ return selected;
174
+ }
175
+ async function chooseTeam(prompter, teams) {
176
+ const selectedId = await prompter.search("Choose a Vercel team or personal scope", teams.map((team) => ({
177
+ value: team.id,
178
+ label: team.name,
179
+ hint: [
180
+ team.slug,
181
+ team.id.startsWith("team_") ? undefined : "personal scope",
182
+ team.current ? "current" : undefined,
183
+ ]
184
+ .filter(Boolean)
185
+ .join(" · "),
186
+ })), teams.find(({ current }) => current)?.id);
187
+ return teams.find(({ id }) => id === selectedId) ?? fail("selected Vercel team disappeared");
188
+ }
189
+ async function chooseProject(services, team) {
190
+ let projects = await services.cli.listProjects(team.slug);
191
+ const modes = [
192
+ ...(projects.length > 0 ? [{ value: "existing", label: "Select an existing project" }] : []),
193
+ { value: "create", label: "Create a dedicated project", hint: "Recommended" },
194
+ ];
195
+ const mode = await services.prompter.select("Choose how to configure the Vercel project", modes, "create");
196
+ if (mode === "existing") {
197
+ const projectId = await services.prompter.search("Choose an existing project", projects.map((project) => ({
198
+ value: project.id,
199
+ label: project.name,
200
+ hint: project.id,
201
+ })));
202
+ return {
203
+ project: projects.find(({ id }) => id === projectId) ?? fail("selected Vercel project disappeared"),
204
+ created: false,
205
+ };
206
+ }
207
+ for (;;) {
208
+ const name = (await services.prompter.text("New project name", DEFAULT_PROJECT_NAME)).trim();
209
+ if (!isValidProjectName(name)) {
210
+ services.reporter.warn("Project names must use 1-100 lowercase letters, digits, dots, underscores, or hyphens and cannot contain three consecutive hyphens.");
211
+ continue;
212
+ }
213
+ if (projects.some((project) => project.name.toLowerCase() === name.toLowerCase())) {
214
+ services.reporter.warn(`Project name "${name}" is already in use. Choose another name.`);
215
+ continue;
216
+ }
217
+ try {
218
+ return { project: await services.cli.createProject(team.slug, name), created: true };
219
+ }
220
+ catch (error) {
221
+ projects = await services.cli.listProjects(team.slug);
222
+ if (projects.some((project) => project.name.toLowerCase() === name.toLowerCase())) {
223
+ services.reporter.warn(`Project name "${name}" became unavailable. Choose another name.`);
224
+ continue;
225
+ }
226
+ throw new Error(`Unable to create project "${name}": ${errorMessage(error)}`, {
227
+ cause: error,
228
+ });
229
+ }
230
+ }
231
+ }
232
+ async function resolveExistingSelection(cli, teams, profile) {
233
+ const team = teams.find(({ id }) => id === profile.teamId);
234
+ if (!team) {
235
+ throw new Error(`Saved Vercel team ${profile.teamSlug} is no longer accessible; rerun setup and choose another team`);
236
+ }
237
+ const project = (await cli.listProjects(team.slug)).find(({ id }) => id === profile.projectId);
238
+ if (!project) {
239
+ throw new Error(`Saved Vercel project ${profile.projectName} is no longer accessible; rerun setup and choose another project`);
240
+ }
241
+ return { team, project };
242
+ }
243
+ async function requestProjectToken(services, selected) {
244
+ services.reporter.message("");
245
+ services.reporter.message(`Create a Vercel access token for team ${selected.team.name} and restrict it to project ${selected.project.name}:`);
246
+ services.reporter.message("https://vercel.com/account/settings/tokens");
247
+ services.reporter.message('A descriptive token name such as "selfbench-local" is recommended.');
248
+ const token = (await services.prompter.secret("Paste the project-scoped access token")).trim();
249
+ if (!token) {
250
+ throw new Error("Vercel access token must not be blank");
251
+ }
252
+ return token;
253
+ }
254
+ function isValidProjectName(value) {
255
+ return /^[a-z0-9._-]{1,100}$/.test(value) && !value.includes("---");
256
+ }
257
+ function formatDuration(timeoutMs) {
258
+ return timeoutMs % (60 * 60 * 1_000) === 0
259
+ ? `${timeoutMs / (60 * 60 * 1_000)}h`
260
+ : `${timeoutMs / (60 * 1_000)}m`;
261
+ }
262
+ function timeoutTier(timeoutClass) {
263
+ return timeoutClass === "45m" ? "Hobby-compatible" : "Pro/Enterprise-compatible";
264
+ }
265
+ function imageRepository(image) {
266
+ return image.slice(0, image.lastIndexOf("@"));
267
+ }
268
+ function imageDigest(image) {
269
+ return image.slice(image.lastIndexOf("@") + 1);
270
+ }
271
+ function defaultProjectRoot() {
272
+ return resolve(dirname(fileURLToPath(import.meta.url)), "..");
273
+ }
274
+ function errorMessage(error) {
275
+ return error instanceof Error ? error.message : String(error);
276
+ }
277
+ function fail(message) {
278
+ throw new Error(message);
279
+ }
280
+ //# sourceMappingURL=vercel-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vercel-setup.js","sourceRoot":"","sources":["../src/vercel-setup.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,8 @@ tasks/
16
16
 
17
17
  Exports include repository snapshots, held-out tests, and reference solutions. They are sensitive and unencrypted; keep them private.
18
18
 
19
+ The provider that generated an export does not constrain where Harbor runs it. Every task has the same provider-neutral Harbor layout, and `manifest.json` records the generation backend and the Harbor environment used for self-bench's nop/oracle gates. For later coding-agent trials, independently choose `--environment docker` or `--environment modal`. Harbor does not currently provide a Vercel environment; Vercel Sandbox is used only during benchmark generation.
20
+
19
21
  ## Run one task
20
22
 
21
23
  Extract the export and select a task:
@@ -25,7 +25,22 @@ self-bench requires GitHub and model credentials:
25
25
 
26
26
  Existing deployments may continue using ChatGPT subscription authentication by providing both `SELFBENCH_PI_AUTH_JSON` and `SELFBENCH_CODEX_AUTH_JSON`. API-key authentication takes precedence when `OPENAI_API_KEY` is set.
27
27
 
28
- ## Execution backends
28
+ Sandbox-provider credentials are separate. Modal accepts its mounted profile or token pair. For a local Vercel worker, `self-bench setup vercel` stores a project-scoped token in an owner-only local profile. Unattended workers use the equivalent `VERCEL_TOKEN`, `VERCEL_TEAM_ID`, and `VERCEL_PROJECT_ID` environment variables. Keep provider credentials on the worker; the API does not need them.
29
+
30
+ ## Execution backends and Harbor
31
+
32
+ SelfBench uses one provider for discovery, authoring, semantic review, and repair sandboxes. It separately invokes Harbor for nop/oracle validation. Docker and Modal default Harbor to the matching environment. Vercel has no Harbor environment, so `--harbor-environment docker|modal` is mandatory.
33
+
34
+ ```bash
35
+ self-bench up --backend docker # Docker + Docker
36
+ self-bench up --backend modal # Modal + Modal
37
+ self-bench up --backend vercel --harbor-environment docker
38
+ self-bench up --backend vercel --harbor-environment modal
39
+ self-bench up --backend docker --harbor-environment modal
40
+ self-bench up --backend modal --harbor-environment docker
41
+ ```
42
+
43
+ Use `--modal-config` whenever either side uses Modal. A worker has one fixed pairing; do not run workers with different provider settings on the same Temporal task queue. Run and export metadata record both choices, plus the effective Vercel timeout cap when applicable.
29
44
 
30
45
  ### Docker
31
46
 
@@ -50,10 +65,95 @@ self-bench up --backend modal
50
65
  self-bench up --backend modal --modal-config /absolute/path/to/.modal.toml
51
66
  ```
52
67
 
53
- `self-bench up` selects both sandbox execution and Harbor validation for the requested backend. Modal mounts `~/.modal.toml` by default; `--modal-config` overrides that path. A secret manager may provide `MODAL_TOKEN_ID` and `MODAL_TOKEN_SECRET` instead. Empty token environment variables are removed at worker startup so they cannot override a valid mounted profile.
68
+ When Modal is used for generation or Harbor, SelfBench mounts `~/.modal.toml` by default; `--modal-config` overrides that path. A secret manager may provide `MODAL_TOKEN_ID` and `MODAL_TOKEN_SECRET` instead. Empty token environment variables are removed at worker startup so they cannot override a valid mounted profile.
54
69
 
55
70
  Modal defaults to 20 concurrent worker activities. Discovery starts eight independently retryable shards, and candidate slots are continuously refilled. Discovery and authoring stop after eight minutes without process output; review stops after five. Discovery also has a 45-minute per-attempt deadline and up to three attempts per shard.
56
71
 
72
+ ### Vercel Sandbox
73
+
74
+ Vercel is a generation backend only; choose Docker or Modal for Harbor. SelfBench supports both Vercel's 45-minute Hobby Sandbox ceiling and the longer paid-team ceiling. Discovery requests 45 minutes, review requests 15 minutes, and authoring and repair request two hours; setup detects the selected project's effective capability and caps every Vercel stage centrally when necessary. Sandbox use, VCR storage, memory, active CPU, and data transfer are metered by Vercel; configure Spend Management before unattended runs. Vercel Hobby use is intended for personal, non-commercial work.
75
+
76
+ #### Interactive local setup
77
+
78
+ Install the current Vercel CLI and make sure Docker is available for the runtime-image build:
79
+
80
+ ```bash
81
+ npm install --global vercel@latest
82
+ self-bench setup vercel
83
+ ```
84
+
85
+ Interactive setup keeps long-running publication and capability checks compact, with a live elapsed timer that freezes when each step completes. Use `self-bench setup vercel --verbose` to stream the underlying Vercel CLI and Docker build output; compact mode reveals retained command output automatically when a step fails.
86
+
87
+ Setup uses Vercel CLI browser login for control-plane selection and VCR publication. It then:
88
+
89
+ 1. shows a searchable team or personal-scope picker;
90
+ 2. offers a searchable existing-project picker or creation of a dedicated project;
91
+ 3. asks for a project name, defaulting to `selfbench-sandbox`, and retries rather than silently suffixing an unavailable name;
92
+ 4. publishes the pinned `Dockerfile.sandbox` runtime to the project's `selfbench-runtime` VCR repository;
93
+ 5. prints the Vercel token page and asks for a manually created access token restricted to the selected project, with terminal echo disabled;
94
+ 6. creates and immediately deletes a one-vCPU, nonpersistent probe sandbox to verify the token, image, command execution, cleanup, and effective duration ceiling;
95
+ 7. activates the profile only after every required check succeeds.
96
+
97
+ The project does not need a deployment. Its metered use is billed to its owning Vercel scope. CLI login and worker configuration are deliberately separate: CLI login selects and provisions resources, while the project-scoped token plus team and project IDs configure the SelfBench worker. Although the Vercel SDK supports ambient OIDC on Vercel infrastructure, SelfBench does not use it.
98
+
99
+ Profiles live in `~/.selfbench/config.json`; tokens live separately in `~/.selfbench/credentials.json`. The directory is mode `0700`, both files are mode `0600`, writes are atomic, and displayed setup output never includes the token. Override the directory with `SELFBENCH_CONFIG_DIR` when isolation is needed. To maintain more than one project profile:
100
+
101
+ ```bash
102
+ self-bench setup vercel --profile secondary
103
+ self-bench up --backend vercel --vercel-profile secondary --harbor-environment modal
104
+ ```
105
+
106
+ Without `--vercel-profile`, `self-bench up` uses the active profile most recently saved by setup. Rerunning setup revalidates the existing project and token by default. It fingerprints the exact Dockerfile—including its digest-pinned base and pinned tool defaults—plus the fingerprint schema and target platform; if the matching immutable VCR image is already ready, publication is skipped. A changed runtime produces a new content-derived tag and digest. The final image reference is always digest-pinned, and existing digests are not deleted automatically. If the default VCR repository contains unrelated images, setup leaves it untouched and asks for another name.
107
+
108
+ When rerunning setup for a named profile, the available actions are:
109
+
110
+ - **Revalidate** keeps the saved team, project, and token. It verifies current access, reuses a compatible ready image, republishes only if the runtime fingerprint changed, reruns the temporary Sandbox capability probe, and refreshes the saved image digest and timeout cap.
111
+ - **Replace the access token** keeps the saved team and project, requests a new project-scoped token, and activates it only after verification succeeds. It replaces only the locally stored credential; revoke the old token separately in Vercel if necessary.
112
+ - **Choose another team or project** repoints the same local profile name after the new project, image, and token pass verification. It does not delete the previous Vercel project or images. Use a different `--profile` name instead when both configurations should remain available.
113
+
114
+ If setup is interrupted after creating a project or VCR repository, it reports the failure and leaves the durable resource in place; rerun setup to continue. It never activates a partial profile. Vercel projects and VCR images are reusable across SelfBench runs and persist after `self-bench down`.
115
+
116
+ #### Start the local worker
117
+
118
+ ```bash
119
+ self-bench up --backend vercel --harbor-environment modal
120
+ # self-bench up --backend vercel --harbor-environment docker
121
+ ```
122
+
123
+ Modal Harbor also needs the Modal profile or token pair. Vercel control credentials are removed from the Harbor child process for both Harbor environments. `self-bench up` resolves the profile, then validates the complete credential triple, digest-pinned image, and timeout cap before starting Compose.
124
+
125
+ The setup probe records a two-hour effective SelfBench ceiling when the requested two-hour sandbox is accepted. If Vercel returns its exact 45-minute limit response, setup verifies a 45-minute sandbox, explains the impact, and asks before saving that cap. Longer authoring and repair requests then run for at most 45 minutes and return exit 124 on timeout, so only the affected candidate is rejected. Discovery and review retain their shorter requested limits. The effective cap is included in run and export metadata.
126
+
127
+ #### Environment-only and unattended workers
128
+
129
+ `self-bench setup vercel` is intentionally interactive. CI and long-running workers can provide the same resolved values through environment variables or a secret manager:
130
+
131
+ ```bash
132
+ export VERCEL_TOKEN=...
133
+ export VERCEL_TEAM_ID=team_...
134
+ export VERCEL_PROJECT_ID=prj_...
135
+ export SELFBENCH_VERCEL_IMAGE='selfbench-runtime@sha256:...'
136
+ export SELFBENCH_VERCEL_TIMEOUT_CAP=2h # use 45m when that is the verified ceiling
137
+
138
+ self-bench up --backend vercel --harbor-environment modal
139
+ ```
140
+
141
+ The image must already have been published from `Dockerfile.sandbox` to the same project's VCR as `linux/amd64`. Use the bare repository-plus-digest form shown above; tags and rolling aliases are rejected. VCR repositories are project-scoped by default, so a sandbox in another project cannot use the image unless the repository is explicitly shared. Explicit token and image values take precedence over profile values, and a lower timeout cap may be supplied; an override cannot exceed the profile's verified ceiling. Supplying a complete credential/image environment requires no local profile; partial team or project overrides are rejected rather than combined across scopes.
142
+
143
+ Vercel defaults to four concurrent worker activities. A standard SelfBench sandbox requests 4 vCPUs, which Vercel pairs with 8 GB of memory, plus 32 GB of ephemeral disk. Unsupported CPU/memory combinations are rejected before allocation. Raise `SELFBENCH_ACTIVITY_CONCURRENCY` only after considering the team's allocation limits and budget. Lower it—often to `1`—when using Docker Harbor on a smaller local machine, because the Vercel-oriented default does not account for local Harbor capacity.
144
+
145
+ Each sandbox run uses a fresh nonpersistent sandbox (`persistent: false`). SelfBench does not create snapshots or resume stopped sandboxes, and it attempts to delete every sandbox when the run ends. If deletion cannot be confirmed, the activity fails so the cleanup problem remains visible. If the worker crashes before cleanup, compute may continue until the provider timeout; Vercel then discards the filesystem, although the stopped sandbox record may remain for up to 14 days unless manually deleted.
146
+
147
+ Cancel active workflows and let cleanup finish before stopping the stack.
148
+
149
+ Common failures:
150
+
151
+ - A newly changed paid plan may take time to propagate its longer timeout entitlement. Rerun `self-bench setup vercel` to repeat the short-lived capability probe and update the saved cap; if a correctly scoped paid project continues to detect 45 minutes, verify team/project ownership before contacting Vercel Support.
152
+ - `not_found` on create usually means the image belongs to another project or is private and unshared. Prefer the same project and a bare digest reference.
153
+ - `image_not_ready` means VCR has not finished optimizing the `linux/amd64` image.
154
+ - Repeated HTTP 429 allocation failures indicate project/team allocation pressure. The executor honors bounded `Retry-After` retries; reduce activity concurrency if pressure continues.
155
+ - Cleanup errors fail the activity rather than silently leaving reusable state and include the exact `selfbench-...` sandbox name for diagnosis.
156
+
57
157
  ## CLI behavior
58
158
 
59
159
  `self-bench run` requires an absolute or relative path to a Git checkout whose `origin` is an HTTPS or SSH GitHub URL. It pins `HEAD`; uncommitted content is excluded.
@@ -112,13 +212,20 @@ SelfBench has no remote deletion route. Delete local artifact-volume data or GCS
112
212
  | `SELFBENCH_ARTIFACT_DIR` | `.selfbench/artifacts` | Local artifact store |
113
213
  | `SELFBENCH_GCS_BUCKET` | — | GCS artifact store |
114
214
  | `SELFBENCH_GCS_PREFIX` | `selfbench` | GCS artifact store |
115
- | `SELFBENCH_EXECUTION_BACKEND` | `docker` | Worker; set by `self-bench up --backend` locally |
116
- | `SELFBENCH_HARBOR_ENVIRONMENT` | execution backend | Worker; set by `self-bench up --backend` locally |
117
- | `SELFBENCH_ACTIVITY_CONCURRENCY` | `1` Docker, `20` Modal | Worker |
215
+ | `SELFBENCH_EXECUTION_BACKEND` | `docker` | Worker; `docker`, `modal`, or `vercel` |
216
+ | `SELFBENCH_DOCKER_IMAGE` | `selfbench-sandbox:local` | Docker worker |
217
+ | `SELFBENCH_HARBOR_ENVIRONMENT` | matching Docker/Modal backend | Worker; required as `docker` or `modal` for Vercel |
218
+ | `SELFBENCH_ACTIVITY_CONCURRENCY` | `1` Docker, `20` Modal, `4` Vercel | Worker |
118
219
  | `SELFBENCH_MODAL_APP` | `selfbench` | Modal worker |
119
220
  | `SELFBENCH_MODAL_ENVIRONMENT` | — | Modal worker |
120
221
  | `SELFBENCH_MODAL_IMAGE` | `node:22-bookworm` | Modal worker |
121
222
  | `SELFBENCH_MODAL_CONFIG_PATH` | `/dev/null` | Compose host mount; set by `self-bench up --modal-config` locally |
223
+ | `SELFBENCH_VERCEL_IMAGE` | profile or — | Required digest-pinned VCR image for Vercel execution |
224
+ | `SELFBENCH_VERCEL_TIMEOUT_CAP` | `2h` | Vercel worker and API; accepts integer milliseconds or `ms`, `s`, `m`, `h` units |
225
+ | `SELFBENCH_CONFIG_DIR` | `~/.selfbench` | Local CLI profile directory; not needed with a complete Vercel environment |
226
+ | `VERCEL_TOKEN` | profile or unset | Vercel worker; explicit project-scoped access token |
227
+ | `VERCEL_TEAM_ID` | profile or unset | Vercel worker |
228
+ | `VERCEL_PROJECT_ID` | profile or unset | Vercel worker; must be able to resolve the configured image |
122
229
  | `SELFBENCH_TEMPORAL_ADDRESS` | `127.0.0.1:7233` | API and worker |
123
230
  | `SELFBENCH_TEMPORAL_NAMESPACE` | `default` | API and worker |
124
231
  | `SELFBENCH_TASK_QUEUE` | `selfbench-dev` | API and worker |
@@ -157,6 +264,20 @@ OPENAI_API_KEY=...
157
264
 
158
265
  The worker owns model, GitHub, Modal, and Harbor credentials. Use separate least-privilege service accounts and a secret manager. Grant GCS object access only to the configured prefix, use a TLS-enabled Temporal namespace, and keep API/worker image digests and `SELFBENCH_TASK_QUEUE` identical.
159
266
 
267
+ For Vercel generation, replace the execution settings above with:
268
+
269
+ ```text
270
+ SELFBENCH_EXECUTION_BACKEND=vercel
271
+ SELFBENCH_HARBOR_ENVIRONMENT=modal # or docker
272
+ SELFBENCH_VERCEL_IMAGE=selfbench-runtime@sha256:...
273
+ SELFBENCH_VERCEL_TIMEOUT_CAP=2h # or the verified 45m ceiling
274
+ VERCEL_TOKEN=...
275
+ VERCEL_TEAM_ID=team_...
276
+ VERCEL_PROJECT_ID=prj_...
277
+ ```
278
+
279
+ Keep the Vercel credential triple on the worker only. A project-scoped token is sufficient when the runtime image belongs to that project. The API must also receive `SELFBENCH_EXECUTION_BACKEND`, `SELFBENCH_HARBOR_ENVIRONMENT`, `SELFBENCH_VERCEL_IMAGE`, and `SELFBENCH_VERCEL_TIMEOUT_CAP` because it stamps the generation backend, Harbor environment, image, and effective timeout cap into each run manifest; it never needs the credential triple.
280
+
160
281
  This repository defines the application boundary, not turnkey cloud infrastructure. Project, region, ingress, IAM, GCS, and Temporal provisioning remain deployment-specific.
161
282
 
162
283
  ## Security boundary
@@ -166,4 +287,5 @@ This repository defines the application boundary, not turnkey cloud infrastructu
166
287
  - Local artifact paths and GCS object names are confined to their configured roots. GCS IAM should enforce the same prefix independently.
167
288
  - Sandboxes receive only the selected model credential: `OPENAI_API_KEY` by default, or a stage-specific subscription credential for compatibility deployments.
168
289
  - Sandboxes contain both a source checkout and a short-lived model credential. Use SelfBench only with repositories you trust to execute; it is not a malware-analysis service.
169
- - Docker uses disposable containers and volumes and removes them after normal completion. A host crash can leave resources for an operator to inspect and remove. Modal uses disposable Sandboxes.
290
+ - Docker uses disposable containers and volumes and removes them after normal completion. A host crash can leave resources for an operator to inspect and remove. Modal uses disposable Sandboxes. Vercel uses nonpersistent named sandboxes, attempts permanent deletion after each run, and fails the activity when deletion cannot be confirmed; inspect the project after worker crashes or cleanup failures.
291
+ - Vercel control credentials authenticate only the worker's Sandbox control plane and are stripped before Harbor starts. They are never workload command secrets.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "self-bench",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Turn completed repository changes into durable, private Harbor evaluations",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -59,12 +59,14 @@
59
59
  "validate": "bun run check && bun run test && bun run build && bun run verify:package"
60
60
  },
61
61
  "dependencies": {
62
+ "@clack/prompts": "1.7.0",
62
63
  "@google-cloud/storage": "^7.17.0",
63
64
  "@temporalio/activity": "^1.13.2",
64
65
  "@temporalio/client": "^1.13.2",
65
66
  "@temporalio/common": "^1.13.2",
66
67
  "@temporalio/worker": "^1.13.2",
67
68
  "@temporalio/workflow": "^1.13.2",
69
+ "@vercel/sandbox": "3.0.0",
68
70
  "modal": "^0.9.0",
69
71
  "zod": "^4.1.12"
70
72
  },
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { parseArgs } from "node:util";
4
4
  import { smokeAllAdapters } from "./agent-smoke.js";
5
+ import { isHarborEnvironment } from "./providers.js";
5
6
 
6
7
  const parsed = parseArgs({
7
8
  options: {
@@ -27,8 +28,8 @@ Options:
27
28
  -h, --help Show this help`);
28
29
  process.exit(0);
29
30
  }
30
- const environment = parsed.values.environment;
31
- if (environment !== "docker" && environment !== "modal") {
31
+ const environment = parsed.values.environment ?? "modal";
32
+ if (!isHarborEnvironment(environment)) {
32
33
  throw new Error("--environment must be docker or modal");
33
34
  }
34
35
  const results = await smokeAllAdapters({
@@ -1,7 +1,9 @@
1
1
  import { mkdir, readFile, writeFile } from "node:fs/promises";
2
2
  import { join, resolve } from "node:path";
3
+ import { harborChildEnvironment } from "./harbor-environment.js";
3
4
  import { parallelMap } from "./parallel.js";
4
5
  import { runCommand } from "./process.js";
6
+ import type { HarborEnvironment } from "./providers.js";
5
7
 
6
8
  export const HARBOR_AGENT_ADAPTERS = [
7
9
  "oracle",
@@ -48,7 +50,7 @@ export interface AdapterSmokeOptions {
48
50
  readonly taskDirectory: string;
49
51
  readonly jobsDirectory: string;
50
52
  readonly harborPath?: string;
51
- readonly environment?: "docker" | "modal";
53
+ readonly environment?: HarborEnvironment;
52
54
  readonly concurrency?: number;
53
55
  }
54
56
 
@@ -99,7 +101,11 @@ export async function smokeAllAdapters(
99
101
  "--yes",
100
102
  "--quiet",
101
103
  ],
102
- { allowFailure: true, timeoutMs: 60 * 60 * 1000 },
104
+ {
105
+ allowFailure: true,
106
+ env: harborChildEnvironment(),
107
+ timeoutMs: 60 * 60 * 1000,
108
+ },
103
109
  );
104
110
  const summary: AdapterSmokeResult = {
105
111
  agent,