Back to blog

Building an AI Agent with YepCode Run for Dynamic Code Execution

Why YepCode Run?

AI agents capable of writing and executing code autonomously are becoming increasingly powerful. However, running AI-generated code securely and efficiently remains a challenge. That's where YepCode Run comes in—a serverless runtime and SDK for executing code in secure sandboxes. In this post, we’ll show how to use YepCode Run to build an AI agent that solves tasks by generating and running code dynamically.

✅ The execution happens in a secure, sandboxed environment. ✅ The infrastructure scales automatically as needed. ✅ You don’t have to worry about dependency management.

YepCode Run provides all of this out of the box so you can focus on your code rather than infrastructure concerns.

How can I use it?

We provide both JavaScript and Python packages, so you may easily integrate YepCode Run in you projects. We have also created a playground page to try any piece of code.

Building an AI Agent That Solves Tasks with Generated Code

Let’s implement an AI-powered agent that takes a task description, generates an executable script, runs it securely using YepCode Run, and iterates if needed. Here’s how it works:

The Prompt

This prompt guides the AI to generate clean, executable JavaScript or Python code that solves a task while sticking to YepCode’s structural standards and package management best practices. 🚀

# Source Code Generation Prompt

Acts as a coding agent to help the user to achieve the described task generating a standalone script in either JavaScript or Python. Do not write any explainations, just write the code. The task is:

=====
{{task}}
=====

## Requirements

- **Output only the raw source code** – no explanations, placeholders, or additional comments beyond required package annotations.
- The script must be **directly executable** without modifications.
- You may use the **following environment variables** already set in the execution context:
  {{envVars}}
- Do not invent any other environment variables neither API keys or credentials. If you don't have the information, just follow another approach.
- **Choose the most suitable language (JavaScript or Python) for solving the problem**.
- **Use external dependencies freely** from npm or pip. You should import them as usually, also add an anotation for us to detect them, and when possible, use binary packages to avoid compilation issues.
  - JavaScript: `// @add-package package_name`
  - Python: `# @add-package package_name`
- **Include debugging logs** (`console.log()` in JavaScript or `print()` in Python) if necessary for execution tracking and error debugging.
- Do not catch errors, let them fail the execution.

## Script Structure

**Follow the required script structure** based on the chosen language:

### JavaScript Structure

```js
// @add-package package_name_1
const package_name_1 = require("package_name_1");
// @add-package package_name_2
const package_name_2 = require("package_name_2");

async function main() {
    // The generated code should go here
    return {"success": true, "data": result}
}

module.exports = { main }
```

### Python Structure

```py
# @add-package package_name_1
import package_name_1
# @add-package package_name_2
from package_name_2.module import Module

def main():
    # The generated code should go here
    return {"success": True, "data": result}
```

Important: The response should only contain the script to be executed by `python` or `node` and follow the exact structure above. Do not include any explanations neither enclosing annotations.

Failed iterations prompt:

## Previous failed executions

You have already tried {{iterations}} times to generate the code for the task but it failed.

### Iteration {{iteration}}

#### Code

{{code}}

#### Error

{{error}}

#### Execution logs

{{logs}}
Show me the code!

We tackle tasks by generating and running code. As LLM we have gone with Anthropic Claude API (Claude 3.5 Sonnet). Our approach is iterative—learning from errors, logs, and past failures to refine each attempt until we get it right.

A standout feature? Seamless handling of environment variables like API keys and passwords. We don’t expose their values to the LLM—YepCode securely manages them at execution time—but we ensure they’re referenced in the prompt.

Our workflow is straightforward:

1. Read the task and environment variables from files.

2. Prompt the LLM to generate code.

3. Execute the code with YepCode.

4. If it works—great! If not, we iterate until it does (or hit the retry limit).

Smart, adaptive, and efficient—just the way automation should be. 🚀

This is the JavaScript full code (python version below):

require("dotenv").config();
const fs = require("fs");
const Anthropic = require("@anthropic-ai/sdk");
const { YepCodeRun, YepCodeEnv } = require("@yepcode/run");

const anthropic = new Anthropic();
const yepcodeRun = new YepCodeRun();
const yepcodeEnv = new YepCodeEnv();

const WRITE_CODE_PROMPT = fs.readFileSync("../prompts/write_code.md", "utf-8");
const WRITE_CODE_APPEND_ERRORS_PROMPT_TITLE = fs.readFileSync(
  "../prompts/write_code_failed_iterations_title.md",
  "utf-8"
);
const WRITE_CODE_APPEND_ERRORS_PROMPT_ITERATION = fs.readFileSync(
  "../prompts/write_code_failed_iterations_body.md",
  "utf-8"
);

const llm = async (prompt) => {
  const msg = await anthropic.messages.create({
    model: "claude-3-5-sonnet-20241022",
    max_tokens: 8192,
    temperature: 0.1,
    messages: [{ role: "user", content: prompt }],
  });
  return msg.content[0].text;
};

const runCode = async (code) => {
  const execution = await yepcodeRun.run(code);
  await execution.waitForDone();
  return execution;
};

const formatLogs = (logs) => {
  return logs
    .map(({ level, message, timestamp }) => `${timestamp} ${level}: ${message}`)
    .join("\n");
};

const solveTask = async (task, envVars) => {
  for (const { key, value, isSensitive } of envVars) {
    await yepcodeEnv.setEnvVar(key, value, isSensitive);
  }

  const MAX_ITERATIONS = 3;
  const iterations = [];

  while (iterations.length < MAX_ITERATIONS) {
    let agentPrompt = WRITE_CODE_PROMPT.replace("{{task}}", task).replace(
      "{{envVars}}",
      envVars.map(({ key }) => `${key}`).join(", ")
    );
    if (iterations.length > 0) {
      agentPrompt += WRITE_CODE_APPEND_ERRORS_PROMPT_TITLE.replace(
        "{{iterations}}",
        iterations.length
      );
      for (let i = 0; i < iterations.length; i++) {
        const iteration = iterations[i];
        agentPrompt +=
          "\n" +
          WRITE_CODE_APPEND_ERRORS_PROMPT_ITERATION.replace(
            "{{iteration}}",
            i + 1
          )
            .replace("{{code}}", iteration.code)
            .replace("{{error}}", iteration.error)
            .replace("{{logs}}", formatLogs(iteration.logs));
      }
    }
    console.log(`\n\n\n### ITERATION ${iterations.length + 1}`);
    console.log(`\n\n#### AGENT PROMPT:\n\n${agentPrompt}`);
    const code = await llm(agentPrompt);
    console.log(`\n\n#### GENERATED CODE:\n\n${code}`);
    console.log("--------------------------------");

    const { returnValue, error, logs } = await runCode(code);
    console.log("--------------------------------");
    if (!error) {
      return returnValue;
    }
    iterations.push({ code, error, logs });
  }
  throw new Error(`Failed to solve task after ${MAX_ITERATIONS} iterations.`);
};

const main = async () => {
  const task = fs.readFileSync("../tasks/task_2.md", "utf-8");
  const envVars = JSON.parse(
    fs.readFileSync("../tasks/task_2_env.json", "utf-8")
  ).map(({ key, value, isSensitive }) => ({
    key,
    value,
    isSensitive,
  }));
  const result = await solveTask(task, envVars);
  console.log(`Result: ${JSON.stringify(result, null, 2)}`);
};

main();

If you prefer the python version:

import os
import json
import re
from dotenv import load_dotenv
from anthropic import Anthropic
from yepcode_run import YepCodeRun, YepCodeEnv

load_dotenv()

anthropic = Anthropic()
yepcode_run = YepCodeRun()
yepcode_env = YepCodeEnv()

with open("../prompts/write_code.md", "r", encoding="utf-8") as f:
    WRITE_CODE_PROMPT = f.read()

with open(
    "../prompts/write_code_failed_iterations_title.md", "r", encoding="utf-8"
) as f:
    WRITE_CODE_APPEND_ERRORS_PROMPT_TITLE = f.read()

with open(
    "../prompts/write_code_failed_iterations_body.md", "r", encoding="utf-8"
) as f:
    WRITE_CODE_APPEND_ERRORS_PROMPT_ITERATION = f.read()


def llm(prompt: str) -> str:
    response = anthropic.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=8192,
        temperature=0.1,
        messages=[{"role": "user", "content": prompt}],
    )
    return response.content[0].text


def run_code(code: str):
    execution = yepcode_run.run(code)
    execution.wait_for_done()
    return execution


def format_logs(logs):
    return "\n".join(f"{log.timestamp} {log.level}: {log.message}" for log in logs)


def solve_task(task: str, env_vars: list) -> any:
    for var in env_vars:
        yepcode_env.set_env_var(var["key"], var["value"], var["isSensitive"])

    MAX_ITERATIONS = 3
    iterations = []

    while len(iterations) < MAX_ITERATIONS:
        agent_prompt = WRITE_CODE_PROMPT.replace("{{task}}", task).replace(
            "{{envVars}}", ", ".join(var["key"] for var in env_vars)
        )

        if iterations:
            agent_prompt += WRITE_CODE_APPEND_ERRORS_PROMPT_TITLE.replace(
                "{{iterations}}", str(len(iterations))
            )

            for i, iteration in enumerate(iterations):
                agent_prompt += (
                    "\n"
                    + WRITE_CODE_APPEND_ERRORS_PROMPT_ITERATION.replace(
                        "{{iteration}}", str(i + 1)
                    )
                    .replace("{{code}}", iteration["code"])
                    .replace("{{error}}", iteration["error"])
                    .replace("{{logs}}", format_logs(iteration["logs"]))
                )

        print(f"\n\n\n### ITERATION {len(iterations) + 1}")
        print(f"\n\n#### AGENT PROMPT:\n\n{agent_prompt}")

        code = llm(agent_prompt)
        print(f"\n\n#### GENERATED CODE:\n\n{code}")
        print("-" * 32)

        execution = run_code(code)
        print("-" * 32)

        if not execution.error:
            return execution.return_value

        iterations.append(
            {"code": code, "error": execution.error, "logs": execution.logs}
        )

    raise Exception(f"Failed to solve task after {MAX_ITERATIONS} iterations.")


def main():
    with open("../tasks/task_2.md", "r", encoding="utf-8") as f:
        task = f.read()

    with open("../tasks/task_2_env.json", "r", encoding="utf-8") as f:
        env_vars = json.load(f)
        env_vars = [
            {
                "key": var["key"],
                "value": var["value"],
                "isSensitive": var.get("isSensitive", False),
            }
            for var in env_vars
        ]

    result = solve_task(task, env_vars)
    print(f"Result: {json.dumps(result, indent=2)}")


main()

The two environment variables needed to run this are:

ANTHROPIC_API_KEY=sk-ant-api...
YEPCODE_API_TOKEN=ey...

What kind of tasks can be solved with this?

As the source code may include any npm or pypi dependency, and you may provide environment variables to connect to private services, the options are endless. For example this task needs to connect to some remote server and then save information in one MySQL server, and the agent has been fully capable to solve it in two iterations:

I need information for the 25 crypto currencies with more 24h Volume. Retrieve the token name, current price and last 24 hours price change.

I need to store the information in a new MySQL table, so create it with the name "crypto_currencies" and the following fields:

- token_name
- current_price
- last_24_hours_price_change

Then insert the retrieved information into the table.

🏁 Conclusion

With YepCode Run, you can create an AI-driven agent that writes, executes, and refines its own code in a secure, serverless environment. Whether you're exploring new ideas, testing AI-generated scripts, or integrating automation into your workflows, YepCode Run has you covered.

Try YepCode Run today and supercharge your AI-powered coding workflows! 🚀

Last articles

See all articles