Build

Agents

On this page

What an agent is

An agent is an AI worker that Valet runs for you. It keeps working after your chat with your coding agent ends: it answers questions in Slack, handles email, or posts a report every morning. When no work is in progress it sleeps, and the next message or scheduled run wakes it.

You describe an agent in a folder:

support-bot/
  SOUL.md              Who the agent is and how it works
  skills/
    refunds/SKILL.md   Instructions for one task
  channels/
    inbox.md           Instructions for one channel
  valet.yaml           Name, description, connectors and channels
  • SOUL.md holds the agent's instructions in plain language.
  • A skill holds instructions for one task. The agent reads it only when the task comes up.
  • A channel is how work reaches the agent, such as a Slack message or a schedule. A file in channels/ holds instructions for one channel.
  • valet.yaml names the agent and lists the connectors and channels it needs.

Create an agent

Ask your agent:

Build a Valet agent called support-bot that answers billing questions
in Slack, and deploy it.

Your agent writes the folder, creates the agent, then publishes the files:

create_service
{ "kind": "agent", "name": "support-bot" }
publish_agent
{
  "name": "support-bot",
  "files": [
    { "path": "valet.yaml", "content": "name: support-bot\ndescription: Answers billing questions in Slack.\n" },
    { "path": "SOUL.md", "content": "You answer billing questions for Acme's support team.\n…" }
  ]
}

Over MCP, create_service creates an empty agent. publish_agent deploys it and waits for deployment to finish. An agent that can run git publishes from a Git push instead of files; see Publish with Git. Chat with the agent in the dashboard. With the CLI, valet new writes starter files, valet agents create creates the agent from the current folder and deploys it with Git, and valet console opens a chat with it. It needs Git 2.32 or later unless it creates the agent from the catalog or a Git URL with --from.

Channels

Every agent has a console channel: the chat in the dashboard and in valet console. Add others to wake the agent in other ways, such as a schedule:

create_channel
{
  "name": "support-bot",
  "channel": "morning-summary",
  "channel_kind": "cron",
  "schedule": "weekdays at 9:00am",
  "timezone": "America/New_York"
}

When a channel fires, the agent follows the instructions in channels/<name>.md, here channels/morning-summary.md.

Webhook

What wakes the agent
A request from another service
Setup
Signed with a secret by default

Cron

What wakes the agent
A schedule, such as weekdays at 9:00
Setup
None

Heartbeat

What wakes the agent
A fixed interval, from 30 seconds to 24 hours
Setup
None

MCP

What wakes the agent
Another AI tool calling the agent as a tool
Setup
A token for each caller, from valet channels token mint

Slack

What wakes the agent
A message or an @mention
Setup
Someone connects Slack to the organization once; each agent then gets its own Slack app

Email

What wakes the agent
Mail to an address such as support@acme.valet.run
Setup
None

create_channel makes cron, heartbeat, webhook and MCP channels. Slack needs a browser, so it starts in the dashboard or the CLI.

Agents aren't the only ones with channels. An app takes webhook, cron and heartbeat channels too; see Webhooks and schedules.

What an agent can use

A connector gives the agent a service's tools, such as HubSpot or Google Drive. Valet adds the credential on each call, so the agent never holds it.

attach_connector
{ "name": "support-bot", "connector": "hubspot" }

When you deploy, Valet attaches each connector and channel valet.yaml names that the organization already has. A manually detached connector returns on the next deploy if valet.yaml still names it. If valet.yaml names a connector or channel the organization doesn't have, or a skill that doesn't exist, the deploy fails and lists what to set up. valet deploy --allow-unsatisfied deploys anyway, and the agent runs without the missing pieces until you add them. See Connectors.

An env var is a named setting. Its value is secret by default: the agent's connectors and channels can use it, but the agent never sees it. Store a value as plain, with "secret": false in set_env_vars or --plain in the CLI, when the agent should read it directly, such as a region.

Skills from your organization's library provide instructions for specific tasks. Attach one a teammate published:

attach_skill
{ "name": "support-bot", "skill": "org:ticket-triage" }

A skill in the agent's own skills/ folder ships with the agent. An attached skill comes from the library and follows its new releases; there is no pin. See Skills.

The agent has memory: tools to remember, recall and forget facts. A memory belongs to one conversation, such as a Slack channel, or to the whole agent. Up to 5 pinned memories reach the agent on every turn. Each agent holds up to 1,000 memories of up to 4 KB each. list_memories and set_memory list and set them, as does valet memories.

Agents run on the claude-sonnet-5 model unless you choose another with valet ps scale agent=<model>.

Changing its own instructions

An agent can propose changes to its own SOUL.md, its own skills and its channel files. Valet's code checks each change before it takes effect:

  • It can't change valet.yaml, so it can't add connectors or channels.
  • It can't change a skill attached from elsewhere.
  • It can make at most 10 changes an hour.
  • If its change conflicts with a person's edit, the person's edit wins.
  • Each change becomes a new release. A failed build leaves the current release running.

Valet's instructions also tell the agent never to change itself because something it read asked it to.

Who can reach it

Only members of your organization can use the console. On every other channel, anyone the channel reaches can talk to the agent:

  • Slack: anyone in the workspace who can message the agent's bot.
  • Email: anyone who sends mail to its address.
  • Webhook: anyone with the URL and its signing secret.
  • MCP: anyone holding a token you minted, and organization members who sign in where MCP sign-in is set up.

Releases

Each publish, with publish_agent or valet deploy, creates a numbered release, v1, v2 and so on, and makes it live. list_releases or valet releases support-bot lists them. Changing a connector or an env var, and each change the agent makes to itself, also creates a release. There is no rollback command: publish the earlier files again.

A blocking release policy can refuse a release. The agent keeps running its current release. See Release policies to review findings in the dashboard's Releases tab.

Run and watch it

list_sessions
{ "name": "support-bot" }

get_logs
{ "name": "support-bot", "kind": "agent" }

scale_service
{ "name": "support-bot", "count": 0 }

restart_service
{ "name": "support-bot" }

These list the agent's conversations, read its logs, pause it, and restart it. get_session, or valet sessions <id>, shows one conversation's transcript. Scaling the agent to 1 resumes it. A restart cuts off conversations in progress.

Next steps