Skip to main content
This open-source project and video are by Code With Antonio, and are featured here with their permission. The code lives in their GitHub repository.

Overview

Grok AI Teammates is an open-source, fullstack app where each bot has a name, a job and a persistent cloud computer of its own. A bot works in its sandbox through shell, file, mouse and keyboard tools, and you can watch its desktop live in the chat. Every chat turn runs as a durable chat agent on Trigger.dev, so a long desktop task survives page refreshes, redeploys and closed tabs. Tech stack: Features:
  • A computer per teammate: each bot gets a persistent Linux sandbox. Files it leaves there are still there next time.
  • Live desktop view: watch a bot move the mouse and type, streamed into the chat over noVNC.
  • Group chats with handoffs: a handoff tool passes the rest of a turn to the teammate whose job it is. A request can’t bounce back to a bot that already held it.
  • Memory across chats: remember and recall tools read and write a notes file in the bot’s sandbox, shared by every conversation the bot is in.
  • Durable turns: the turn loop, streaming and transcript storage all run in a chat.agent() task on Trigger.dev.
  • Plans and usage limits: model spend is recorded per turn in onTurnComplete; sandbox time is metered every 5 minutes by a scheduled task that stops sandboxes once an owner runs out.

GitHub repo

View the AI Teammates repo

Click here to view the full code for this project on GitHub. It’s maintained by Code With Antonio, and you can fork it and use it as a starting point for your own project.

How it works

The chat agent

One chat.agent() answers every chat, direct or group. The browser sends the botId a message is addressed to as typed client data, and the agent loads that bot’s job and instructions from the database on every turn, so edits to a bot apply to the next message. Tools are built per chat in the tools callback: every bot gets its sandbox tools, and group chats also get the handoff tool. Declaring them on the agent config keeps screenshot tool results as images when earlier turns are replayed. The run function returns the managed streamText with 2 stop conditions: a 50-step cap for desktop work, and the user’s remaining model budget.
trigger/chat.ts
The idempotencyKey on each usage record is built from the run ID and turn number, so a retried onTurnComplete can’t charge the same turn twice.

Metering sandboxes with a scheduled task

Daytona stops idle sandboxes on its own and doesn’t report running time, so the app measures it by looking. A scheduled task runs every 5 minutes, charges each running sandbox’s owner for the interval, and stops the sandboxes of owners with no hours left:
trigger/usage.ts

The Next.js chat UI

The browser talks to the agent directly through useTriggerChatTransport. Server actions check that the signed-in user owns the chat and has a plan with the bots feature before they start a session or mint a session-scoped access token. Previous messages load with useLoadTranscript from the agent’s default transcript storage:
components/chat.tsx
actions/chat.ts

Running it

You need accounts with Clerk, Neon, Trigger.dev and Daytona (Sentry is optional). Set the variables listed in the repo’s README in .env.local, including TRIGGER_SECRET_KEY and TRIGGER_PROJECT_REF, then push the schema and run the app and the tasks in 2 terminals:
To deploy, run npx trigger.dev@latest deploy and add the tasks’ variables (DATABASE_URL, CLERK_SECRET_KEY, DAYTONA_API_KEY and the Neon AI gateway settings) on the Environment Variables page of your production environment. The repo’s README covers the Clerk Billing setup and hosting the Next.js app.

Relevant code

  • Chat agent: trigger/chat.ts: the chat.agent() definition, per-chat tools, handoffs, instructions, and per-turn usage recording
  • Sandbox metering: trigger/usage.ts: the scheduled task that charges and stops running sandboxes
  • Global hooks: trigger/init.ts: Sentry setup with tasks.onFailure, tasks.onWait and tasks.onComplete hooks that flush logs before a run freezes
  • Sandbox tools: lib/sandbox-tools.ts: shell, file, mouse, keyboard, screenshot and memory tools on the bot’s Daytona sandbox
  • Handoff tool: lib/handoff-tool.ts: passes a group chat turn to another bot
  • Server actions: actions/chat.ts: session start, token minting and transcript loading, each behind an ownership and plan check
  • Chat UI: components/chat.tsx: useTriggerChatTransport, useLoadTranscript and useChat
  • Trigger.dev config: trigger.config.ts: retries, max duration and the Sentry source map build extension

Learn more

AI chat overview

How chat agents, sessions, and the turn loop work.

Frontend

The chat transport, session tokens, and reconnection.

Tools

Declaring tools on your agent and how they persist across turns.

Scheduled tasks

Run tasks on a cron schedule.