Open sourceEarly access

Your agent, as code

Start with a simple bot and grow it into the agent your whole company runs on. Integrations, skills, and automations are plain TypeScript files in a sandbox: no framework to learn, nothing you can't read. Open source, in early access now.

How it grows

Start with a bot. End up running the company.

Everything your agent knows lives in files, so it grows the way software grows: review, history, rollback, ownership. One bot becomes a repo your whole company runs on.

01

Ship a simple bot

A bug bot, a QA bot, a digest before standup. One file, an afternoon, and it is answering in the channel.

02

Grow it like software

Add integrations, skills, memory, and schedules as plain files. Diff them in review, revert them in git, grep them at 2am.

03

Run the company on it

The same repo becomes the agent every team works in, from Slack to GitHub to cron, on Adapt Cloud or your own infrastructure.

The shape of it

Not a framework. Just code.

Slack, GitHub, Messages, or a schedule: every surface is the same small file. An event comes in, your code runs, an LLM call goes out. It is just code, so it can become anything.

  • Just code

    No DSL, no lifecycle hooks, no magic imports. If you can read JavaScript, you already know exactly what these bots do.

  • A few small helpers

    llm.complete() is a function you own, not an interface you implement. Change the prompt, the model, the context. It is your file.

  • Runs in your sandbox

    Integrations, skills, and automations are all the same thing: code executing in your Firecracker sandbox with your filesystem mounted.

integrations/slack/bot.ts
1// Slack bot webhook. Verifies signatures, listens for
2// mentions and DMs, then answers with an LLM run.
3import { App } from '@slack/bolt'
4import { llm, fetchContext } from '@adapt/sdk'
5
6const app = new App({
7 token: process.env.SLACK_BOT_TOKEN,
8 signingSecret: process.env.SLACK_SIGNING_SECRET,
9})
10
11async function runLLM(history) {
12 const lines = ['You are a helpful assistant on Slack.']
13 for (const turn of history) {
14 lines.push(`${turn.role}: ${turn.content}`)
15 }
16 return llm.complete(lines.join('\n'))
17}
18
19app.event('app_mention', async ({ event, say }) => {
20 const history = await fetchContext(event.channel)
21 await say(await runLLM(history))
22})

The full file is ~200 lines, and every one is yours to read and change.

Inside the repo

Your company, as code.

One command scaffolds plain TypeScript. No framework to learn, no config screens. Every integration is a file you own, so each team meets the agent inside the tool they already live in.

acme-agent· main

acme/

Yours from the first commit. Read it, fork it, delete what you don't need.

One codebase, every team

Push and deploy.

Ship it to your own environment, or use Adapt Cloud's managed platform.

Trusted code

The code we run, handed to you.

This isn't a starter template. It's the code Adapt's managed cloud is built on, given to you the way shadcn/ui gives you components: as code, not a dependency. Run it, edit it, delete from it, make it your own. Here is all it takes to triage #bugs:

integrations/slack/triage.ts
1// Watches #bugs. Every new report gets triaged:
2// severity, area, owner, and a linked issue.
3import { app, llm, linear } from '@adapt/sdk'
4
5app.message({ channel: '#bugs' }, async ({ message, say }) => {
6 const triage = await llm.complete(
7 `Triage this bug. Severity, area, owner: ${message.text}`,
8 { schema: Triage },
9 )
10
11 const issue = await linear.createIssue({
12 title: triage.title,
13 priority: triage.severity,
14 team: triage.area,
15 })
16
17 await say({
18 thread_ts: message.ts,
19 text: `${triage.severity} · ${triage.area} → ${issue.url}`,
20 })
21})

21 lines. Ship it before lunch, tune the prompt in review.

acme.slack.com
Search Acme

bugs

GH

Grace Hopper2:14 PM

Checkout is throwing 500s when a cart has a gift card. Started about 20 minutes ago, a few customers have written in already.

Acme logo

AcmeAPP2:14 PM

S1 · checkout · routed to @payments-eng

ACME-482 · Linearpossible duplicate of ACME-471

Own it from the
first commit.

It's early, and that's the point: come shape it. Show us what you build, tell us where it hurts.