Skip to content

Use slash commands

Every gateway-enabled agent (--with-slack, --with-telegram, --with-teams) ships with a unified slash-command surface. The same commands work the same way on every channel — typed as the first word of a message.

Built-in commands

Command Aliases What it does
/help Lists every registered command for the current agent.
/new /reset Clears the session — fresh conversation memory.
/usage Turn count and a token-cost estimate for the current session.
/stop Cooperatively cancels the running turn (tools that check get_cancel_event(session_id) exit early).
/personality /persona Switch a runtime personality overlay. See below.
/cron Schedule, list, pause, resume, run, or remove jobs. See below.

Anything that isn't a registered command is forwarded to the agent unchanged.

Personalities

Personalities are runtime system-prompt overlays — lighter than --persona/SOUL.md, switchable per session, no rebuild needed. The two systems coexist; SOUL.md is baked at scaffold time, personalities flip at runtime.

Storage

Drop markdown files at ~/.nuvel/personalities/<name>.md:

---
name: concise
description: Short, direct answers — no preamble, no filler.
---

You are a concise assistant. Answer in as few words as possible.
Skip greetings, qualifiers, and meta-commentary. Get to the point.

YAML frontmatter is optional. The body is what gets prepended to each user turn while the personality is active.

Usage

> /personality
Available personalities:
  concise — Short, direct answers — no preamble, no filler.
  socratic — Teaches by asking questions before giving answers.
No personality is active. Use /personality <name>.

> /personality concise
Personality set to 'concise'.

> /personality off
Personality cleared.

Examples shipped

The gateway-base overlay includes three example personalities (concise, socratic, pirate) under <agent_package>/gateways/personalities_examples/. Copy any you want to use into ~/.nuvel/personalities/.

Adding your own command

The registry lives at <agent_package>/gateways/commands.py. Register with the @command decorator:

from .commands import command, CommandContext, CommandResult

@command("/insights", help="Show this week's insights")
async def cmd_insights(ctx: CommandContext) -> CommandResult:
    return CommandResult(handled=True, replies=["Top 3 things this week: ..."])

CommandContext carries user_id, channel, session_id, the raw text, and a reply(text) callable. CommandResult is {handled: bool, replies: list[str]}. New commands work on every channel automatically — no per-gateway code.

Cron / scheduled jobs

The /cron command lets you schedule recurring or one-shot agent runs. The scheduler is opt-in — set NUVEL_CRON_ENABLED=1 on the agent service. See Cron env vars for tuning, and Deploy to Railway → cron before shipping.

Subcommands

/cron list
/cron add "<schedule>" "<prompt>" [--name <n>] [--deliver origin|local|slack:<ch>|telegram:<chat_id>]
/cron pause <id>
/cron resume <id>
/cron run <id>
/cron remove <id>

Schedule formats

Format Example Behavior
Relative one-shot 30m, 2h, 1d Runs once after that delay.
Interval recurring every 30m, every 2h, every 1d Runs forever until removed.
Cron expression 0 9 * * *, 0 */6 * * * Standard 5-field cron. Runs forever.
ISO timestamp 2026-12-15T09:00:00 One-shot at that absolute time (UTC if no offset).

Delivery options

Token What it does
origin (default on a gateway) Deliver back to the channel where /cron add was sent.
local Write the output file only — no message. Useful for log-only jobs.
slack:<channel> Send to a specific Slack channel.
telegram:<chat_id> Send to a specific Telegram chat.

Silent suppression

If the agent's response starts with [SILENT], delivery is suppressed (the output file is still written). Useful for monitoring jobs that should only ping when something is wrong:

/cron add "every 5m" "Check if our health endpoint returns 200. Reply [SILENT] if healthy, otherwise describe the failure." --name health-watch

From chat (without typing /cron)

Because cronjob is a registered tool, you can also just ask:

"Every morning at 9am, summarize my unread emails and post to #standup."

The agent will call cronjob(action="create", ...) itself. The /cron command is the explicit-control path; natural language is the conversational path. Both write to the same job store.

Recursion guard

A cron-spawned agent run cannot create or modify other cron jobs. This is enforced via an internal NUVEL_CRON_RUNNING env flag — the cronjob tool refuses mutations when it's set. Read-only list/get still work.

Voice memos

When GATEWAY_TRANSCRIBE_AUDIO=1, voice notes on Slack and Telegram are transcribed (Whisper via OpenAI or Groq) before reaching the agent — the audio attachment is replaced with [Voice memo, M:SS]: <transcript> and forwarded as a normal text turn. Full env-var reference: Voice transcription.