# Run a Fireworks Coding Agent with BYOK Secrets

[Fireworks AI](https://fireworks.ai) serves the most popular open models (Kimi, DeepSeek, Qwen, GLM, and more) through an OpenAI-compatible inference API, alongside a fine-tuning platform for training on your own data. Daytona provides the other half of an agent stack: isolated sandboxes where model-generated code can run safely.

This guide connects the two. A coding agent runs **inside a Daytona sandbox**, calls a Fireworks open model for reasoning, and iterates on a task until its tests pass. The Fireworks API key is handled as a **BYOK (bring your own key) secret**: it never enters the sandbox in plaintext, cannot be read by agent code, and cannot be sent to any host other than `api.fireworks.ai`. When the run completes, the agent's full trajectory is exported in the exact format Fireworks accepts as supervised fine-tuning data.

---

### 1. Workflow Overview

The example consists of a host script and an in-sandbox agent:

1. **Secret setup** — `main.py` stores your Fireworks key as a Daytona organization secret with a host allowlist of `api.fireworks.ai`, or rotates the value if the secret already exists
2. **Sandbox creation** — a Python sandbox is created with the secret mounted as the `FIREWORKS_API_KEY` environment variable; the variable holds an opaque placeholder, not the key
3. **Agent run** — `agent.py` executes inside the sandbox: a tool-calling loop (`write_file`, `run_bash`) against a Fireworks model, tasked with making `python tests.py` pass
4. **Verification** — the tests are rerun as the final verdict; their exit code is the kind of verifiable signal a reward function consumes in reinforcement learning
5. **Data export** — the complete message history is saved as `trajectory.jsonl` and downloaded to the host, ready for `firectl dataset create`

### 2. Project Setup

#### Clone the Repository

Clone the [Daytona guides repository](https://github.com/daytona/guides) and navigate to the example directory:

```bash
git clone https://github.com/daytona/guides.git
cd guides/python/fireworks/coding-agent
```

#### Create Virtual Environment and Install

```bash
python -m venv venv
source venv/bin/activate  # macOS/Linux; Windows PowerShell: .\venv\Scripts\Activate.ps1
pip install -e .
```

#### Configure Environment

Copy `.env.example` to `.env` and fill in your keys:

```bash
DAYTONA_API_KEY=         # https://app.daytona.io/dashboard/keys
FIREWORKS_API_KEY=       # https://app.fireworks.ai (keys start with "fw_")
# Optional: override the default model (accounts/fireworks/models/kimi-k3)
# with any serverless model from https://fireworks.ai/models
# FIREWORKS_MODEL=
```

Your Fireworks key is used once, on the host, to create the Daytona secret. It is never uploaded to the sandbox.

Your Daytona API key needs `manage:secrets` to create and rotate the secret (otherwise create the secret in the dashboard — the script prints exact instructions and continues), `write:sandboxes` to create sandboxes and mount the secret, and `delete:sandboxes` for cleanup at the end of the run.

#### Run

```bash
python main.py
```

### 3. BYOK: How the Secret Protects Your Key

The host stores the key as an organization [secret](https://www.daytona.io/docs/secrets.md) scoped to Fireworks' API host:

```python
daytona.secret.create(CreateSecretParams(
    name="fireworks-api-key",
    value=fireworks_key,
    hosts=["api.fireworks.ai"],
))
```

Mounting the secret at sandbox creation sets the environment variable to the secret's placeholder token:

```python
sandbox = daytona.create(CreateSandboxFromSnapshotParams(
    language="python",
    secrets={"FIREWORKS_API_KEY": "fireworks-api-key"},
))
```

Daytona's outbound proxy substitutes the real key into HTTPS request headers, but only for requests to `api.fireworks.ai`. The example proves both halves of this model at runtime:

```
✓ Value inside the sandbox: dtn_secret_... (opaque placeholder)
✓ Fireworks auth check from sandbox: HTTP 200
```

`printenv` shows the placeholder — the plaintext key is not in the sandbox environment, filesystem, or process arguments. The `200` from an authenticated call proves substitution works, because Fireworks rejects the placeholder with a `401`. A request to any other host carries the unmodified placeholder, so agent code cannot exfiltrate the key, and [response scrubbing](https://www.daytona.io/docs/secrets.md#response-scrubbing) prevents it from ever reading the real value.

### 4. Understanding the Agent

The agent is deliberately minimal (~200 lines) and runs entirely inside the sandbox. Because Fireworks exposes an OpenAI-compatible API, it uses the standard `openai` client preinstalled in the default Python sandbox:

```python
client = OpenAI(
    base_url="https://api.fireworks.ai/inference/v1",
    api_key=os.environ["FIREWORKS_API_KEY"],  # the placeholder
)
```

It advertises two tools to the model and loops until the model stops calling them:

- `write_file(path, content)` — create or overwrite a file
- `run_bash(command)` — run a shell command, returning output and exit code

The task ships as `tests.py`: implement `slugify()` in `solution.py` so all cases pass, including Unicode normalization and hyphen collapsing. Every file the model writes and every command it runs executes in the isolated sandbox — nothing touches your machine.

### 5. Verification and Fine-Tuning Data Export

After the loop ends, the agent restores a pristine snapshot of `tests.py` — taken before the model could touch the filesystem — and reruns it as the final verdict, so the model cannot tamper its way to a passing reward. It then writes the full conversation — system, user, assistant (including `tool_calls`), and tool messages — as a single JSONL row:

```json
{"messages": [{"role": "system", "..."}, {"role": "assistant", "tool_calls": ["..."]}, {"role": "tool", "..."}]}
```

This is the OpenAI messages format, which Fireworks uses directly for supervised fine-tuning. Fireworks datasets require between 3 and 3 million examples, so concatenate a few verified runs and upload the result:

```bash
cat trajectory.jsonl >> trajectories.jsonl   # append after each verified run
firectl dataset create my-agent-trajectories trajectories.jsonl   # once it has 3+ rows
```

Run the example across many tasks, keep the trajectories that pass verification, and the result is an SFT dataset distilled from your own agent's verified behavior — the standard precursor to [reinforcement learning on the Fireworks Training API](https://docs.fireworks.ai/fine-tuning/training-api/cookbook/agentic-rl). One caveat before scaling up: in this demo `tests.py` doubles as the task spec the model may read, so a solution could in principle memorize the visible cases. Production reward functions should also score held-out cases the policy never sees.

### 6. Use Fireworks in Other Daytona Guides

This guide calls Fireworks through the raw OpenAI-compatible API, but every framework-based Daytona guide works with Fireworks models too — set the provider's package and model string, plus `FIREWORKS_API_KEY`:

- **[LangChain data analysis](https://www.daytona.io/docs/guides/langchain/langchain-data-analysis.md)** — `pip install langchain-fireworks`, then `MODEL=fireworks:accounts/fireworks/models/kimi-k3`
- **[Mastra coding agent](https://www.daytona.io/docs/guides/mastra/mastra-coding-agent.md)** — `MODEL=fireworks-ai/accounts/fireworks/models/kimi-k3`
- **[Vercel AI SDK benchmark agent](https://www.daytona.io/docs/guides/vercel-ai-sdk/vercel-ai-sdk-multi-language-benchmark-agent-sandbox.md)** — `npm install @ai-sdk/fireworks@2` (the major matching that example's `ai` v6), then `fireworks('accounts/fireworks/models/kimi-k3')`

The BYOK pattern from this guide applies unchanged: store the key as a host-scoped secret instead of a plain environment variable whenever the agent code runs inside the sandbox.

### 7. Next Steps

- **Bring your own task** — replace `tests.py` with anything gradeable by exit code: unit tests, linters, SQL result checks, build success
- **Scale out** — create sandboxes in parallel for batch trajectory generation; see the [OpenEnv guide](https://www.daytona.io/docs/guides/reinforcement-learning/openenv-finqa.md) for the 500-sandbox pool pattern
- **Close the loop with RL** — the `tests.py` exit code used here is exactly the reward a verifier computes in Fireworks' [Agentic RL cookbook](https://docs.fireworks.ai/fine-tuning/training-api/cookbook/agentic-rl). Daytona's [reinforcement learning guides](https://www.daytona.io/docs/guides/reinforcement-learning/openenv-finqa.md) cover multi-turn RL training with sandboxed environments end to end

---

**Key advantages of this approach:**

- **Keys stay out of the blast radius**: the credential powering the agent is unreadable and unexfiltratable from the environment where untrusted model-generated code runs
- **Open models, drop-in client**: Fireworks' OpenAI-compatible API means no agent-code changes versus any other provider
- **Verified-by-construction data**: trajectories are graded before they become training data
- **One environment from inference to training**: the same sandbox pattern scales from a single agent run to parallel rollout generation for RL

Need help? - [Reach support](mailto:support@daytona.io)