コンテンツにスキップ

Build a Coding Agent Using OpenCode Web and Daytona

View as Markdown

このコンテンツはまだ日本語訳がありません。

This guide demonstrates how to run the OpenCode coding agent inside a Daytona sandbox environment using OpenCode’s easy-to-use web interface.

The agent can develop web apps, write code in any language, install dependencies, and run scripts. It supports over 75 different LLM providers and can start dev servers with preview links for live apps.


1. Workflow Overview

When you launch the main script, a Daytona sandbox is created and OpenCode is installed inside it. OpenCode is configured with a custom Daytona-aware agent.

The script provides a preview link to access the web interface, where you can create, configure and interact with agent sessions:

$ npm run start
Creating sandbox...
Installing OpenCode...
Starting OpenCode web server...
Press Ctrl+C to stop.
█▀▀█ █▀▀█ █▀▀█ █▀▀▄ █▀▀▀ █▀▀█ █▀▀█ █▀▀█
█░░█ █░░█ █▀▀▀ █░░█ █░░░ █░░█ █░░█ █▀▀▀
▀▀▀▀ █▀▀▀ ▀▀▀▀ ▀ ▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀
Web interface: https://3000-1e0f775c-c01b-40e7-8c64-062fd3dadd75.proxy.daytona.works/

The agent can host web apps and provide you with a preview link using the Daytona Preview Links feature. When your task involves running or previewing a web application, the agent automatically reasons about this need, hosts the app, and generates a preview link for you to inspect the live result:

Web app demo generated by OpenCode coding agent

You can continue interacting with your agent until you are finished. When you exit the program, the sandbox will be deleted automatically.

2. Project Setup

Clone the Repository

First, clone the Daytona repository and navigate to the example directory:

Terminal window
git clone https://github.com/daytonaio/daytona.git
cd daytona/guides/typescript/opencode

Configure Environment

Get your API key from the Daytona Dashboard.

Copy .env.example to .env and add your key:

Terminal window
DAYTONA_API_KEY=your_daytona_key

Local Usage

Install dependencies:

Terminal window
npm install

Run the example:

Terminal window
npm run start

The OpenCode web interface will start and wait for you to open it in your browser.

Models and API Providers

OpenCode works with over 75 LLM providers, with a free provider selected by default. You can change the model or provider at any time using the menu below the prompt input in the web interface. If your chosen provider needs an API key, you’ll be prompted to enter it.

Persisting API Keys

To persist API keys between uses of the script, you can set them as environment variables when creating the Daytona sandbox.

For example, to use an Anthropic API key, modify the daytona.create() call in src/index.ts to include your desired API key:

sandbox = await daytona.create({
envVars: {
ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY || '',
},
})

3. Understanding the Script

This example consists of a Node.js script that installs, configures and runs OpenCode inside a Daytona sandbox.

Initialization

On initialization, the main script:

  1. Creates a new Daytona sandbox.
  2. Installs OpenCode globally inside the sandbox using npm with process execution.
  3. Creates and uploads a custom agent configuration with Daytona-specific system prompt.
  4. Starts the OpenCode web server inside the sandbox on port 3000.
  5. Substitutes the URL in OpenCode’s output with a Daytona preview link for the web interface.

Main Script Code

The script creates a session and executes OpenCode as an asynchronous command, which allows it to stream output while keeping the process alive:

const command = await sandbox.process.executeSessionCommand(sessionId, {
command: `${envVar} opencode web --port ${OPENCODE_PORT}`,
runAsync: true,
})

When OpenCode starts its web server, it prints a link to its web UI using a localhost address (e.g., http://127.0.0.1:3000). However, since the sandbox runs remotely, this localhost link is only accessible inside the sandbox itself. To solve this, the script parses OpenCode’s output, and replaces the URL with the corresponding Daytona preview link.

const opencodePreviewLink = await sandbox.getPreviewLink(OPENCODE_PORT)
const replaceUrl = (text: string) =>
text.replace(
new RegExp(`http:\\/\\/127\\.0\\.0\\.1:${OPENCODE_PORT}`, 'g'),
opencodePreviewLink.url
)

OpenCode Agent Configuration

A custom system prompt is used to instruct the agent on how to use Daytona sandbox paths and preview links. This prompt is packaged into a JSON configuration string, which is passed to the sandbox as the OPENCODE_CONFIG_CONTENT environment variable:

{
"$schema": "https://opencode.ai/config.json",
"default_agent": "daytona",
"agent": {
"daytona": {
"description": "Daytona sandbox-aware coding agent",
"mode": "primary",
"prompt": "You are running in a Daytona sandbox. Use the /home/daytona directory instead of /workspace for file operations. When running services on localhost, they will be accessible as: <PREVIEW_URL_PATTERN>. When starting a server, always give the user the preview URL to access it. When starting a server, start it in the background with & so the command does not block further instructions."
}
}
}

The <PREVIEW_URL_PATTERN> in the agent prompt is a template URL where {PORT} is a placeholder for the port to access on the Daytona sandbox. This template string is created by generating a preview link for a specific port number and then replacing the port number with {PORT}.

Clean up

When you press Ctrl+C, the script automatically cleans up by deleting the sandbox:

process.once('SIGINT', async () => {
console.log('\nCleaning up...')
if (sandbox) await sandbox.delete()
process.exit(0)
})

Key advantages:

  • Secure, isolated execution in Daytona sandboxes
  • OpenCode Web interface accessible via browser
  • Support for 75+ LLM providers
  • All agent code execution happens inside the sandbox
  • Automatic preview link generation for deployed services
  • Custom agent configuration for Daytona-specific workflows
  • Clean resource management with automatic sandbox cleanup