Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/vibe-coding-platform/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).

This project integrates [Workflow DevKit](https://useworkflow.dev/) to support a durable and reliable AI agent with automatic retries and state management.

## Getting Started

First, run the development server:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
export default `Use this tool to create a new Vercel Sandbox — an ephemeral, isolated Linux container that serves as your development environment for the current session. This sandbox provides a secure workspace where you can upload files, install dependencies, run commands, start development servers, and preview web apps. Each sandbox is uniquely identified and must be referenced for all subsequent operations (e.g., file generation, command execution, or URL access).
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly I had to change these from md files since workflow devkit doesn't currently let you provide your own loaders to the workflow bundling interface

Hope this isn't a blocker. We'd like to support custom loaders in devkit but that isn't high priority


## When to Use This Tool

Use this tool **once per session** when:

1. You begin working on a new user request that requires code execution or file creation
2. No sandbox currently exists for the session
3. The user asks to start a new project, scaffold an application, or test code in a live environment
4. The user requests a fresh or reset environment

## Sandbox Capabilities

After creation, the sandbox allows you to:

- Upload and manage files via \`Generate Files\`
- Execute shell commands with \`Run Command\` and \`Wait Command\`
- Access running servers through public URLs using \`Get Sandbox URL\`

Each sandbox mimics a real-world development environment and supports rapid iteration and testing without polluting the local system. The base system is Amazon Linux 2023 with the following additional packages:

\`\`\`
bind-utils bzip2 findutils git gzip iputils libicu libjpeg libpng ncurses-libs openssl openssl-libs pnpm procps tar unzip which whois zstd
\`\`\`

You can install additional packages using the \`dnf\` package manager. You can NEVER use port 8080 as it is reserved for internal applications. When requested, you need to use a different port.

## Best Practices

- Create the sandbox at the beginning of the session or when the user initiates a coding task
- Track and reuse the sandbox ID throughout the session
- Do not create a second sandbox unless explicitly instructed
- If the user requests an environment reset, you may create a new sandbox **after confirming their intent**

## Examples of When to Use This Tool

<example>
User: Can we start fresh? I want to rebuild the project from scratch.
Assistant: Got it — I'll create a new sandbox so we can start clean.
*Calls Create Sandbox*
</example>

## When NOT to Use This Tool

Skip using this tool when:

1. A sandbox has already been created for the current session
2. You only need to upload files (use Generate Files)
3. You want to execute or wait for a command (use Run Command / Wait Command)
4. You want to preview the application (use Get Sandbox URL)
5. The user hasn't asked to reset the environment

## Summary

Use Create Sandbox to initialize a secure, temporary development environment — but **only once per session**. Treat the sandbox as the core workspace for all follow-up actions unless the user explicitly asks to discard and start anew.
`
92 changes: 46 additions & 46 deletions apps/vibe-coding-platform/ai/tools/create-sandbox.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import type { UIMessage, UIMessageStreamWriter } from 'ai'
import type { UIMessageChunk } from 'ai'
import type { DataPart } from '../messages/data-parts'
import { Sandbox } from '@vercel/sandbox'
import { getRichError } from './get-rich-error'
import { tool } from 'ai'
import description from './create-sandbox.prompt'
import z from 'zod/v3'
import { getWritable } from 'workflow'

const inputSchema = z.object({
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The refactor for tools is very simple

  1. we have to pull the execute function to the top level since use step only works top level. Opened Supporting "use step" and "use workflow" inside arrow functions workflow#219 to track this in workflow
  2. Got rid of the old writable wiring through and I'm just getting the writable directly inside steps thanks to workflow's getWritable

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend reviewing with "hide whitespace" enabled

timeout: z
Expand All @@ -24,61 +25,60 @@ const inputSchema = z.object({
),
})

const createSandboxStep =
(writer: UIMessageStreamWriter<UIMessage<never, DataPart>>) =>
async (
{ timeout, ports }: z.infer<typeof inputSchema>,
{ toolCallId }: { toolCallId: string }
) => {
async function createSandboxStep(
{ timeout, ports }: z.infer<typeof inputSchema>,
{ toolCallId }: { toolCallId: string }
) {
'use step'

const writable = getWritable<UIMessageChunk<never, DataPart>>()
const writer = writable.getWriter()

writer.write({
id: toolCallId,
type: 'data-create-sandbox',
data: { status: 'loading' },
})

try {
const sandbox = await Sandbox.create({
timeout: timeout ?? 600000,
ports,
})

writer.write({
id: toolCallId,
type: 'data-create-sandbox',
data: { status: 'loading' },
data: { sandboxId: sandbox.sandboxId, status: 'done' },
})

try {
const sandbox = await Sandbox.create({
timeout: timeout ?? 600000,
ports,
})

writer.write({
id: toolCallId,
type: 'data-create-sandbox',
data: { sandboxId: sandbox.sandboxId, status: 'done' },
})

return (
`Sandbox created with ID: ${sandbox.sandboxId}.` +
`\nYou can now upload files, run commands, and access services on the exposed ports.`
)
} catch (error) {
const richError = getRichError({
action: 'Creating Sandbox',
error,
})
return (
`Sandbox created with ID: ${sandbox.sandboxId}.` +
`\nYou can now upload files, run commands, and access services on the exposed ports.`
)
} catch (error) {
const richError = getRichError({
action: 'Creating Sandbox',
error,
})

writer.write({
id: toolCallId,
type: 'data-create-sandbox',
data: {
error: { message: richError.error.message },
status: 'error',
},
})
writer.write({
id: toolCallId,
type: 'data-create-sandbox',
data: {
error: { message: richError.error.message },
status: 'error',
},
})

console.log('Error creating Sandbox:', richError.error)
return richError.message
}
console.log('Error creating Sandbox:', richError.error)
return richError.message
}
}

export const createSandbox = ({
writer,
}: {
writer: UIMessageStreamWriter<UIMessage<never, DataPart>>
}) =>
export const createSandbox = () =>
tool({
description,
inputSchema,
execute: createSandboxStep(writer),
execute: createSandboxStep,
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
export default `Use this tool to generate and upload code files into an existing Vercel Sandbox. It leverages an LLM to create file contents based on the current conversation context and user intent, then writes them directly into the sandbox file system.

The generated files should be considered correct on first iteration and suitable for immediate use in the sandbox environment. This tool is essential for scaffolding applications, adding new features, writing configuration files, or fixing missing components.

All file paths must be relative to the sandbox root (e.g., \`src/index.ts\`, \`package.json\`, \`components/Button.tsx\`).

## When to Use This Tool

Use Generate Files when:

1. You need to create one or more new files as part of a feature, scaffold, or fix
2. The user requests code that implies file creation (e.g., new routes, APIs, components, services)
3. You need to bootstrap a new application structure inside a sandbox
4. You're completing a multi-step task that involves generating or updating source code
5. A prior command failed due to a missing file, and you need to supply it

## File Generation Guidelines

- Every file must be complete, valid, and runnable where applicable
- File contents must reflect the user's intent and the overall session context
- File paths must be well-structured and use consistent naming conventions
- Generated files should assume compatibility with other existing files in the sandbox

## Best Practices

- Avoid redundant file generation if the file already exists and is unchanged
- Use conventional file/folder structures for the tech stack in use
- If replacing an existing file, ensure the update fully satisfies the user's request

## Examples of When to Use This Tool

<example>
User: Add a \`NavBar.tsx\` component and include it in \`App.tsx\`
Assistant: I'll generate the \`NavBar.tsx\` file and update \`App.tsx\` to include it.
*Uses Generate Files to create:*
- \`components/NavBar.tsx\`
- Modified \`App.tsx\` with import and usage of \`NavBar\`
</example>

<example>
User: Let's scaffold a simple Express server with a \`/ping\` route.
Assistant: I'll generate the necessary files to start the Express app.
*Uses Generate Files to create:*
- \`package.json\` with Express as a dependency
- \`index.js\` with basic server and \`/ping\` route
</example>

## When NOT to Use This Tool

Avoid using this tool when:

1. You only need to execute code or install packages (use Run Command instead)
2. You're waiting for a command to finish (use Wait Command)
3. You want to preview a running server or UI (use Get Sandbox URL)
4. You haven't created a sandbox yet (use Create Sandbox first)

## Output Behavior

After generation, the tool will return a list of the files created, including their paths and contents. These can then be inspected, referenced, or used in subsequent commands.

## Summary

Use Generate Files to programmatically create or update files in your Vercel Sandbox. It enables fast iteration, contextual coding, and dynamic file management — all driven by user intent and conversation context.
`
Loading