the universal sandbox runtime for agents and humans. pocketenv.io
sandbox openclaw agent claude-code vercel-sandbox deno-sandbox cloudflare-sandbox atproto sprites daytona
7
fork

Configure Feed

Select the types of activity you want to include in your feed.

add logs

+126 -123
+2
apps/sandbox/src/providers/modal/mod.ts
··· 168 168 tokenId: options?.modalTokenId || env.MODAL_TOKEN_ID!, 169 169 tokenSecret: options?.modalTokenSecret || env.MODAL_TOKEN_SECRET!, 170 170 }); 171 + consola.log("Getting Modal sandbox with ID:", id); 171 172 const sandbox = await modal.sandboxes.fromId(id); 173 + consola.log("Got Modal sandbox with ID:", id, sandbox); 172 174 return new ModalSandbox(sandbox); 173 175 } 174 176 }
+124 -123
apps/sandbox/src/routes/sandboxes.ts
··· 83 83 name = `${name}-${suffix}`; 84 84 } while (true); 85 85 86 - const record = await c.var.db.transaction(async (tx) => { 87 - const user = await tx 88 - .select() 89 - .from(users) 90 - .where(eq(users.did, c.var.did || "")) 91 - .execute() 92 - .then((res) => res[0]); 86 + const { record: initialRecord, user } = await c.var.db.transaction( 87 + async (tx) => { 88 + const user = await tx 89 + .select() 90 + .from(users) 91 + .where(eq(users.did, c.var.did || "")) 92 + .execute() 93 + .then((res) => res[0]); 93 94 94 - let [record] = await tx 95 - .insert(sandboxes) 96 - .values({ 97 - base: params.base, 98 - name, 99 - provider: params.provider, 100 - publicKey: process.env.PUBLIC_KEY!, 101 - userId: user?.id, 102 - instanceType: "standard-1", 103 - keepAlive: params.keepAlive, 104 - sleepAfter: params.sleepAfter, 105 - status: "INITIALIZING", 106 - }) 107 - .returning() 108 - .execute(); 95 + const [record] = await tx 96 + .insert(sandboxes) 97 + .values({ 98 + base: params.base, 99 + name, 100 + provider: params.provider, 101 + publicKey: process.env.PUBLIC_KEY!, 102 + userId: user?.id, 103 + instanceType: "standard-1", 104 + keepAlive: params.keepAlive, 105 + sleepAfter: params.sleepAfter, 106 + status: "INITIALIZING", 107 + }) 108 + .returning() 109 + .execute(); 109 110 110 - if (params.secrets.length > 0) { 111 - await saveSecrets(tx, record, { secrets: params.secrets }); 112 - } 111 + if (params.secrets.length > 0) { 112 + await saveSecrets(tx, record, { secrets: params.secrets }); 113 + } 113 114 114 - if (params.variables.length > 0) { 115 - await saveVariables(tx, record, { variables: params.variables }); 116 - } 115 + if (params.variables.length > 0) { 116 + await saveVariables(tx, record, { variables: params.variables }); 117 + } 117 118 118 - if (params.spriteToken && user?.id) { 119 - await tx 120 - .insert(spriteAuth) 121 - .values({ 122 - sandboxId: record.id, 123 - spriteToken: params.spriteToken, 124 - redactedSpriteToken: params.redactedSpriteToken ?? "", 125 - userId: user.id, 126 - } satisfies InsertSpriteAuth) 127 - .execute(); 128 - } 119 + if (params.spriteToken && user?.id) { 120 + await tx 121 + .insert(spriteAuth) 122 + .values({ 123 + sandboxId: record.id, 124 + spriteToken: params.spriteToken, 125 + redactedSpriteToken: params.redactedSpriteToken ?? "", 126 + userId: user.id, 127 + } satisfies InsertSpriteAuth) 128 + .execute(); 129 + } 129 130 130 - if (params.daytonaApiKey && user?.id) { 131 - await tx 132 - .insert(daytonaAuth) 133 - .values({ 134 - sandboxId: record.id, 135 - apiKey: params.daytonaApiKey, 136 - redactedApiKey: params.redactedDaytonaApiKey ?? "", 137 - userId: user.id, 138 - organizationId: params.daytonaOrganizationId!, 139 - } satisfies InsertDaytonaAuth) 140 - .execute(); 141 - } 131 + if (params.daytonaApiKey && user?.id) { 132 + await tx 133 + .insert(daytonaAuth) 134 + .values({ 135 + sandboxId: record.id, 136 + apiKey: params.daytonaApiKey, 137 + redactedApiKey: params.redactedDaytonaApiKey ?? "", 138 + userId: user.id, 139 + organizationId: params.daytonaOrganizationId!, 140 + } satisfies InsertDaytonaAuth) 141 + .execute(); 142 + } 142 143 143 - if (params.denoDeployToken && user?.id) { 144 - await tx 145 - .insert(denoAuth) 146 - .values({ 147 - sandboxId: record.id, 148 - deployToken: params.denoDeployToken, 149 - redactedDenoToken: params.redactedDenoDeployToken ?? "", 150 - userId: user.id, 151 - } satisfies InsertDenoAuth) 152 - .execute(); 153 - } 154 - 155 - if (params.vercelApiToken && user?.id) { 156 - await tx 157 - .insert(vercelAuth) 158 - .values({ 159 - sandboxId: record.id, 160 - vercelToken: params.vercelApiToken, 161 - redactedVercelToken: params.redactedVercelApiToken ?? "", 162 - userId: user.id, 163 - projectId: params.vercelProjectId!, 164 - teamId: params.vercelTeamId!, 165 - }) 166 - .execute(); 167 - } 144 + if (params.denoDeployToken && user?.id) { 145 + await tx 146 + .insert(denoAuth) 147 + .values({ 148 + sandboxId: record.id, 149 + deployToken: params.denoDeployToken, 150 + redactedDenoToken: params.redactedDenoDeployToken ?? "", 151 + userId: user.id, 152 + } satisfies InsertDenoAuth) 153 + .execute(); 154 + } 168 155 169 - if (params.modalTokenId && user?.id) { 170 - await tx 171 - .insert(modalAuth) 172 - .values({ 173 - sandboxId: record.id, 174 - tokenId: params.modalTokenId!, 175 - redactedTokenId: params.redactedModalTokenId!, 176 - tokenSecret: params.modalTokenSecret!, 177 - redactedTokenSecret: params.redactedModalTokenSecret!, 178 - userId: user.id, 179 - }) 180 - .execute(); 181 - } 156 + if (params.vercelApiToken && user?.id) { 157 + await tx 158 + .insert(vercelAuth) 159 + .values({ 160 + sandboxId: record.id, 161 + vercelToken: params.vercelApiToken, 162 + redactedVercelToken: params.redactedVercelApiToken ?? "", 163 + userId: user.id, 164 + projectId: params.vercelProjectId!, 165 + teamId: params.vercelTeamId!, 166 + }) 167 + .execute(); 168 + } 182 169 183 - const sandbox = await createSandbox(params.provider, { 184 - id: record.id, 185 - keepAlive: params.keepAlive, 186 - sleepAfter: params.sleepAfter, 187 - snapshotRoot: process.env.DENO_SNAPSHOT_ROOT, 188 - spriteToken: decrypt(params.spriteToken), 189 - spriteName, 190 - daytonaApiKey: decrypt(params.daytonaApiKey), 191 - organizationId: params.daytonaOrganizationId, 192 - denoDeployToken: decrypt(params.denoDeployToken), 193 - vercelApiToken: decrypt(params.vercelApiToken), 194 - vercelProjectId: params.vercelProjectId, 195 - vercelTeamId: params.vercelTeamId, 196 - modalTokenId: decrypt(params.modalTokenId), 197 - modalTokenSecret: decrypt(params.modalTokenSecret), 198 - image: images[params.base] || images["openclaw"], 199 - }); 200 - const sandboxId = await sandbox.id(); 170 + if (params.modalTokenId && user?.id) { 171 + await tx 172 + .insert(modalAuth) 173 + .values({ 174 + sandboxId: record.id, 175 + tokenId: params.modalTokenId!, 176 + redactedTokenId: params.redactedModalTokenId!, 177 + tokenSecret: params.modalTokenSecret!, 178 + redactedTokenSecret: params.redactedModalTokenSecret!, 179 + userId: user.id, 180 + }) 181 + .execute(); 182 + } 201 183 202 - [record] = await tx 203 - .update(sandboxes) 204 - .set({ 205 - status: "RUNNING", 206 - sandboxId: sandboxId, 207 - startedAt: new Date(), 208 - vcpus: params.vcpus, 209 - memory: params.memory, 210 - disk: params.disk, 211 - }) 212 - .where(eq(sandboxes.id, record.id)) 213 - .returning() 214 - .execute(); 184 + return { record, user }; 185 + }, 186 + ); 215 187 216 - return record; 188 + const sandbox = await createSandbox(params.provider, { 189 + id: initialRecord.id, 190 + keepAlive: params.keepAlive, 191 + sleepAfter: params.sleepAfter, 192 + snapshotRoot: process.env.DENO_SNAPSHOT_ROOT, 193 + spriteToken: decrypt(params.spriteToken), 194 + spriteName, 195 + daytonaApiKey: decrypt(params.daytonaApiKey), 196 + organizationId: params.daytonaOrganizationId, 197 + denoDeployToken: decrypt(params.denoDeployToken), 198 + vercelApiToken: decrypt(params.vercelApiToken), 199 + vercelProjectId: params.vercelProjectId, 200 + vercelTeamId: params.vercelTeamId, 201 + modalTokenId: decrypt(params.modalTokenId), 202 + modalTokenSecret: decrypt(params.modalTokenSecret), 203 + image: images[params.base] || images["openclaw"], 217 204 }); 205 + const sandboxId = await sandbox.id(); 206 + 207 + const [record] = await c.var.db 208 + .update(sandboxes) 209 + .set({ 210 + status: "RUNNING", 211 + sandboxId: sandboxId, 212 + startedAt: new Date(), 213 + vcpus: params.vcpus, 214 + memory: params.memory, 215 + disk: params.disk, 216 + }) 217 + .where(eq(sandboxes.id, initialRecord.id)) 218 + .returning() 219 + .execute(); 218 220 219 221 return c.json(record); 220 222 } catch (err) { ··· 309 311 .execute(), 310 312 ]); 311 313 312 - await sandbox.setupDefaultSshKeys(); 313 - 314 314 Promise.all([ 315 + sandbox.setupDefaultSshKeys(), 315 316 ...sandboxFileRecords 316 317 .filter((x) => x.files !== null) 317 318 .map((r) =>