Batteries included

The boring 80% is already built.

Everything a conversation needs to be useful — knowledge, tools, identity, deployments — and none of it yours to operate.

Knowledge base

Markdown in knowledge/, or point sources.yml at a site and let it crawl.

Tools, two ways

JavaScript for real logic, declarative YAML for a plain HTTP call.

CRM that fills itself

One contact per visitor. Every tool sees it on every turn, read-only.

Silent authentication

A verified number or your own resolve decides who the visitor is.

Preview, live, rollback

diff before you push, rollback when it reads worse in the wild.

Widget and web chat

A public chat page and an embeddable bubble, themed from the widget block of vatio.yml.

Evals, not vibes

Replay real conversations against a new manifest before you promote it.

Secrets and diagnostics

secrets set keeps credentials out of git. chat debug shows every tool call.

Multilingual by default

Replies in the language the visitor wrote in. Nothing to configure.


The whole workspace

A directory, not a platform.

Everything the platform runs for you is a file you can read, diff and review. There is no state hiding in a dashboard that your repository doesn't know about.

Which is also why a coding agent can build one: it is the kind of thing agents are already good at — writing a few small files that have to validate.

agent/ the manifest
vatio.yml          # required — workspace, business, widget, agent
knowledge/
  hours.md         # markdown you wrote
  sources.yml      # or a site to crawl
tools/
  check_availability.js   # real logic
  lookup_order.yml        # one HTTP call
lib/
  format.js        # shared helpers, no spec
auth/
  member.js        # silent resolve()

Knowledge

Write it, or point at a site.

Drop Markdown into knowledge/ — the first # heading becomes the title, the rest is the body. For anything already published, declare the pages in knowledge/sources.yml and the platform indexes them for you.

Retrieval is semantic first and falls back to keyword search, so a question phrased nothing like your page still finds it.

knowledge/sources.yml crawled for you
- name: blog
  site_url: https://example.com
  url_pattern: "/blog/**"
- name: docs
  site_url: https://example.com
  url_pattern: "/docs/*"

Tools

Two kinds, because most tools aren't code.

A tool that needs real logic is a JavaScript file. A tool that is nothing but "call one endpoint and relay the answer" is a YAML file, and Vatio makes the call natively — no sandbox round-trip. The filename is the tool key either way.

tools/check_availability.js logic
export const spec = {
  description: "Check whether a class has open spots.",
  when_to_use: "The visitor asks if a class is free.",
  parameters: {
    type: "object",
    properties: { class_name: { type: "string" } },
    required: ["class_name"]
  },
  access: "public"
};
tools/check_availability.yml one HTTP call
description: "Check whether a class has open spots."
when_to_use: "The visitor asks if a class is free."
parameters:
  type: object
  properties:
    class_name: { type: string }
  required: [class_name]

every tool, every turn read-only
// JavaScript tool
ctx.contact.name
ctx.contact.email
ctx.contact.phone_number

# Declarative HTTP tool
$contact.name
$contact.email
$contact.phone_number

CRM and identity

The contact record fills itself.

Vatio keeps one contact per visitor per workspace and environment — name, email, phone, plus the channel identities they arrived on. You don't create it or manage it; the runtime does, and every tool sees it on every turn.

Authentication is silent: a scheme is a provider file. Creating auth/member.js creates the member scheme that tools reference as access: member. No OTP challenge to design, nothing to register.


Channels

A channel decides how messages arrive. Nothing else.

The same runtime, agent, tools and safeguards serve all of them. Branching on ctx.channel.type is for the rare case where behavior genuinely must differ — deciding whether a channel is trustworthy enough for authentication, say.

Web

A public chat page at vatio.ai/w/<slug>, plus an embeddable bubble you paste into any site. Serves the live deployment.

WhatsApp

Your own Meta number on live, or Vatio's shared preview number from day one. How the preview works.

CLI

vatio chat always talks to preview and never delivers a real message — so you can iterate without touching a customer.


Deployments

Immutable snapshots, two pointers.

A deployment is a frozen copy of the manifest. push moves the preview pointer, publish moves the live pointer, rollback moves it back. Nothing is rebuilt and nobody has to redeploy.

push is idempotent: it creates the remote workspace the first time and reuses it afterwards. There is no separate link or create step to remember.

~/agents/acme the whole lifecycle
vatio push        # validate + update preview
vatio status      # preview / live state
vatio diff        # what changed vs. remote preview
vatio publish     # promote preview → live
vatio rollback    # restore previous live

All of it, on one page.

Every feature here has a section in the docs — quick start, concepts, CLI and API in a single document your agent can read in one request.