52 lines
2.4 KiB
Markdown
52 lines
2.4 KiB
Markdown
# CopilotKit × Daytona — `runCode` showcase
|
||
|
||
The deployable demo behind the [Daytona cookbook recipe](../../../showcase/shell-docs/src/content/docs/cookbook/daytona.mdx).
|
||
A minimal CopilotKit **Built-in Agent** app whose only added capability is a `runCode` server tool that executes
|
||
Python / TypeScript / JavaScript inside an isolated [Daytona](https://www.daytona.io) sandbox and streams the
|
||
result back to the chat — with a custom `useRenderTool` card (fixed-height streaming code pane with
|
||
syntax highlighting and a fixed-height result pane).
|
||
|
||
## What's inside
|
||
|
||
- `app/api/copilotkit-single/route.ts` — the recipe's `runCode` tool wired into a `BuiltInAgent` on
|
||
`createCopilotEndpointSingleRoute`. Pure recipe code (Python/TS/JS via `daytona.create({ language })`).
|
||
- `app/page.tsx` — `CopilotKitProvider` + `CopilotSidebar` + a `useRenderTool({ name: "runCode" })`
|
||
renderer using `react-syntax-highlighter` (Prism + `vscDarkPlus`, mirroring
|
||
`@copilotkit/react-ui`'s own `CodeBlock`).
|
||
- A system prompt that tells the agent the tool result is rendered directly to the user, so it
|
||
doesn't restate stdout in chat text.
|
||
|
||
## Prerequisites
|
||
|
||
- Node 18+
|
||
- An OpenAI API key (`OPENAI_API_KEY`) — the recipe defaults to `openai:gpt-5.4-mini`, overridable via
|
||
the `MODEL` env var.
|
||
- A Daytona API key (`DAYTONA_API_KEY`) — create one in the
|
||
[Daytona dashboard](https://app.daytona.io/dashboard/keys).
|
||
|
||
## Run locally
|
||
|
||
```bash
|
||
npm install
|
||
echo "OPENAI_API_KEY=sk-…" > .env.local
|
||
echo "DAYTONA_API_KEY=…" >> .env.local
|
||
npm run dev # http://localhost:3000
|
||
```
|
||
|
||
Open the page, click into the sidebar chat, and ask something like:
|
||
|
||
> Run a Python snippet that prints the first 10 Fibonacci numbers.
|
||
|
||
> Run JavaScript that logs Date.now().
|
||
|
||
## Notes
|
||
|
||
- This is a **standalone npm project** — intentionally not in the monorepo's `pnpm-workspace.yaml`.
|
||
`npm install` here installs against published `@copilotkit/*@1.58.0`, which is the same surface the
|
||
recipe targets.
|
||
- `new Daytona()` throws at module load if `DAYTONA_API_KEY` is missing, so the app won't boot without
|
||
it. That's by design — the key is required, not optional.
|
||
- For arbitrary languages beyond Python/TS/JS, swap `sandbox.process.codeRun` for
|
||
`sandbox.process.executeCommand(...)` and optionally use a custom Daytona `Image` with the toolchain
|
||
preinstalled. See the recipe's _Going further_ section.
|