Zvessa docs

AI jobs

Streaming replies, background builds, model sizes and notes.

Every piece of AI work in a space is an AI job: a chat reply, a bot's thought, a request an outside AI hands over through MCP. Jobs are general, so anything that needs Claude with tools runs on the same engine (code: convex/aiJobs.ts, convex/lib/ai/).

What people see #

How a job runs #

start → queued | running → one model turn per background step → done | failed | cancelled

Model sizes #

Spaces never name a model; they pick a size at /ai/model:

SettingWhat runs
auto (default)Small edits and short questions go to the fast model; building, anything new, web research and long asks go to the careful one.
smallAlways the fast model (claude-haiku-5-5), low effort.
largeAlways the careful model (claude-opus-5-5), medium effort.

If the fast model gets stuck (it declines, runs out of room, or keeps making invalid changes), the job starts over once on the careful model. The chat block can also ask for a size per message (ai.chat prop model).

/ai settings #

All optional, changed like any setting (HQ, propose_change, MCP):

{ "ai": { "model": "auto", "stream": true, "remember": false, "notify": true, "maxTurns": 10 } }

AI notes #

Short notes on how each person likes things built ("Prefers dark looks", "Calls members crew"). One list per person per space, at most 30, each under 200 characters. They go into the AI's instructions for that person's jobs. Notes are about style: anything that looks like an email, a phone number, a key or a password is refused, and in kids spaces the AI is told never to note anything about a child. People read, add and delete their notes on the ai.notes block.

Blocks #

BlockWhat it is
ai.chatThe builder chat itself (the dashboard's AI pane is this block). Props: placeholder, model, steps.
ai.modelModel size, streaming and finish pushes (writes /ai).
ai.notesWhat the AI remembers about the viewer; add, delete, notes on or off.
ai.jobsThe space's latest AI work with Stop for running jobs. Props: title, limit.

Kit: AI helper (ai-helper, group Build) adds an owner-only "AI" page with ai.model, ai.notes and ai.jobs, and sets /ai/remember to true.

Tools (MCP and the in-app AI) #

ToolScopeWhat it does
list_notesreadThe caller's notes in this space.
remember_noteproposeKeep a note (refused when notes are off).
forget_noteproposeRemove a note by id or exact text.
list_ai_jobsreadLatest jobs: status, step, size, turns, tokens. MCP only.
ask_space_aiproposeHand a request to the space's own AI, as if typed in the chat. MCP only.
cancel_ai_jobproposeStop a queued or running job. MCP only.

The in-app AI gets the note tools only where notes are on.

For engines (bots, automations) #

const turn = await ctx.runMutation(internal.kits.ailimits.limits.take, { workspaceId, userId: null, source: "bot" });
if (!turn.ok) return; // turn.limit.message says why
const jobId = await ctx.runMutation(internal.aiJobs.start, {
  workspaceId, kind: "bot", bot: "greeter", ref: runId,
  prompt: "A new member joined: say hi in #lobby",
  system: "You greet new members warmly, in one line.",
  tools: ["post_message"],            // narrows the tool list; approve tools are never given
  tier: "small", maxTurns: 6, key: turn.key,
  callback: "kits/bots/engine:_thought", // called with { ref, jobId, text, status, proposalIds }
});

internal.aiJobs.cancel({ jobId }) stops it; internal.aiJobs._get({ jobId }) reads it. Tools run through runTool with caller.for (the person) and caller.bot set.