Wizard Setup
Interactive assistant setup with cogitator wizard.
Overview
The cogitator wizard command provides an interactive TUI to configure a personal AI assistant. It generates a cogitator.yml config and .env file with all required secrets.
Quick Start
npx @cogitator-ai/cli wizardThe wizard walks you through:
- Names — your name and the assistant's name (used in the default personality)
- LLM provider and model — Google, Anthropic, OpenAI, or Ollama (local, or a remote/cloud URL with an optional API key); models are fetched live
- Channels — Telegram, Discord, Slack: bot token and owner user IDs (Slack also asks for the signing secret and an optional
xapp-app token for Socket Mode). The terminal channel is always on - Capabilities — web search, file system (allowed paths), GitHub (token), device tools, browser (visible window / stealth), scheduler, RAG (paths to index), self-config, self-tools
- MCP servers — any command line, quoted arguments supported
- Memory — SQLite database path
- Personality — the system prompt, pre-filled from the names above
The wizard sets up only Telegram, Discord and Slack. Add WhatsApp and WebChat to cogitator.yml by hand; --edit keeps those entries.
Secrets are merged into .env (written with mode 0600) without removing your other variables or comments. If cogitator.yml already exists, the wizard asks before overwriting it.
After setup, start the assistant:
cogitator upcogitator up finds cogitator.yml (or cogitator.yaml, or --config <path>) in the current directory, reads .env next to it, builds the runtime with RuntimeBuilder and starts every channel. up runs the assistant in a child process and restarts it whenever it exits with code 78 — the owner /restart command and self-config updates; --no-restart-loop runs it in-process without that supervisor, so /restart just stops it.
Editing an Existing Config
Re-run the wizard with --edit to modify an existing cogitator.yml:
cogitator wizard --editThis loads the current config and pre-fills every prompt. Leaving a secret blank keeps the value already in .env; existing MCP servers and settings the wizard does not ask about (security, rate limits, stream tuning, compaction) are preserved. The wizard only sets up SQLite memory, but a memory.adapter: postgres config is kept as is (the SQLite path prompt is skipped). channels.whatsapp and channels.webchat, which the wizard does not ask about, are kept too.
Generated Files
cogitator.yml
name: jarvis
personality: |-
You are jarvis, a personal AI assistant for Alex.
Be concise, friendly, and proactive. Use tools when they can help.
Remember important things about Alex using memory tools.
llm:
provider: google
model: google/gemini-3.8-flash
channels:
telegram:
ownerIds:
- '123456789'
capabilities:
webSearch: true
scheduler: true
memory:
adapter: sqlite
path: ~/.cogitator/memory.db
autoExtract: true
knowledgeGraph: true
compaction:
threshold: 50
stream:
flushInterval: 600
minChunkSize: 30.env
GOOGLE_API_KEY=your-api-key
TG_TOKEN=your-telegram-bot-tokenProgrammatic Equivalent
Instead of the wizard, you can use RuntimeBuilder directly. It validates the config with AssistantConfigSchema and fills in the schema defaults, so only name, personality and llm are required:
import { RuntimeBuilder } from '@cogitator-ai/channels';
const builder = new RuntimeBuilder(
{
name: 'jarvis',
personality: 'You are Jarvis, a personal AI assistant for Alex.',
llm: { provider: 'google', model: 'google/gemini-3.8-flash' },
channels: { telegram: { ownerIds: ['123456789'] } },
capabilities: { webSearch: true, scheduler: true },
memory: { path: '~/.cogitator/memory.db', compaction: { threshold: 50 } },
},
process.env
);
const runtime = await builder.build();
await runtime.gateway.start();
process.on('SIGTERM', async () => {
await runtime.cleanup(); // stops the scheduler and gateway, closes memory, MCP and browser
process.exit(0);
});build() returns { agent, cogitator, gateway, scheduler, cleanup }; scheduler is null unless capabilities.scheduler is on. An invalid config throws a ZodError from the constructor. The optional third argument takes:
| Option | Description |
|---|---|
configPath | Path of cogitator.yml, needed (with configHelpers) for the selfConfig tools |
configHelpers | { parseYaml, stringifyYaml, validateConfig } used by the config_read / config_update tools |
onRestart | Called on /restart or after a config update; default process.exit(78) (RESTART_EXIT_CODE) |
hooks | HookRegistry passed to the gateway (see Lifecycle Hooks) |
approvals | GatewayApprovalsConfig merged over the config's approvals block; the code value wins, so use it for what YAML cannot hold, such as a custom format |
The second argument is the environment the runtime reads keys and tokens from; it is not copied into process.env.
Config Reference
cogitator.yml is validated by AssistantConfigSchema (exported from @cogitator-ai/channels, with AssistantConfigInput / AssistantConfigOutput types).
| Field | Type | Default | Description |
|---|---|---|---|
name | string | required | Assistant name (also the agent name and memory namespace) |
personality | string | required | System prompt; date, core facts and capability notes are appended |
llm.provider | google | openai | anthropic | ollama | required | LLM provider |
llm.model | string | required | Model id; the provider prefix is added when missing (e.g. google/gemini-3.8-flash) |
channels.telegram / discord / slack | { ownerIds?: string[] } | — | Enables the channel; the first owner id gets owner commands and self-config access |
channels.whatsapp | { ownerIds?: string[], sessionPath?: string } | session ~/.cogitator/whatsapp-session | WhatsApp; owner ids are phone numbers without @s.whatsapp.net |
channels.webchat | { port?: number, path?: string } | port: 8080, path: '/ws' | WebChat; starts only with WEBCHAT_TOKEN set, has no owners |
capabilities.webSearch | boolean | — | web_search tool, added only when a Tavily, Brave or Serper key is set |
capabilities.fileSystem.paths | string[] | home dir | file_* tools, restricted to these paths |
capabilities.github | boolean | — | github_api tool (needs GITHUB_TOKEN) |
capabilities.deviceTools | boolean | — | Clipboard, system info and screenshot tools |
capabilities.browser | boolean | { headless, stealth } | headless: true | Playwright browser tools via @cogitator-ai/browser (Chromium is installed on first run) |
capabilities.scheduler | boolean | — | Scheduler tools and heartbeat |
capabilities.rag.paths | string[] | — | Index these paths with @cogitator-ai/rag (needs an embedding key for the provider) |
capabilities.selfConfig | boolean | — | Config/env tools — usable only by channel owners and the local terminal |
capabilities.selfTools | boolean | { path } | ~/.cogitator/tools | create_tool & co.; created tools load on restart, create_tool asks for approval in chat |
mcpServers.<name> | { command, args, env? } | — | Stdio MCP servers whose tools are added (needs @cogitator-ai/mcp) |
memory.adapter | sqlite | postgres | sqlite | Memory storage backend |
memory.path | string | ~/.cogitator/memory.db | SQLite file (also holds core facts with Postgres) |
memory.connectionString | string | DATABASE_URL | Postgres connection (or POSTGRES_URL; the graph needs pg) |
memory.knowledgeGraph | boolean | true | Knowledge graph and remember / recall / forget tools |
memory.autoExtract | boolean | true | Auto-extract entities from conversations |
memory.compaction.threshold | number | — | Messages in a conversation before compaction (keeps the 10 newest) |
security.dmPolicy | open | allowlist | pairing | disabled | open | Who may DM the assistant (see DM Policy) |
security.allowlist | string[] | — | Allowed users, telegram:42 or bare ids |
security.groupPolicy | open | allowlist | disabled | open | Which group chats the assistant answers |
security.groupAllowlist | string[] | — | Allowed group/chat ids |
security.storePath | string | ~/.cogitator/dm-allowlist.json | Where paired users are saved |
security.commandAccess.authorized | string[] | — | Users who may run /status, /sessions, /help |
security.commandAccess.publicCommands | string[] | — | Owner commands anyone may run |
stream.flushInterval | number | 600 | Stream flush interval (ms) |
stream.minChunkSize | number | 30 | Minimum buffered text before a flush |
rateLimit.maxPerMinute | number | 30 | Per-user rate limit, applied only when rateLimit is set |
approvals.approveWords / denyWords | string[] | approve, yes, да, одобряю / deny, no, нет, отклоняю | Replies that answer a tool approval prompt; replace the defaults |
approvals.notAllowedMessage | string | English notice | Sent when someone other than the run's user answers |
Without a security block no DM policy is applied and everyone can talk to the assistant. Owner commands are enabled when at least one channel has ownerIds. Tool approvals in chat use the default reply words unless the approvals block sets others; a custom prompt format can only be set in code (RuntimeBuilder's approvals option).
WhatsApp and WebChat
channels:
whatsapp:
ownerIds:
- '15551234567'
sessionPath: ~/.cogitator/whatsapp-session
webchat:
port: 8080
path: /ws
approvals:
approveWords: [approve, yes, ok]
denyWords: [deny, no]
notAllowedMessage: Only the requester can answer this.WhatsApp needs @whiskeysockets/baileys (and qrcode-terminal to print the pairing QR) and pairs on the first cogitator up. WebChat needs ws and WEBCHAT_TOKEN in .env; without the token the channel is skipped with a warning, since an open socket would give anyone the assistant's tools. Clients connect to ws://host:8080/ws?token=<WEBCHAT_TOKEN>.
Environment Variables
RuntimeBuilder reads these from the environment it is given (cogitator up: the process environment plus .env):
| Variable | Used for |
|---|---|
GOOGLE_API_KEY (or GEMINI_API_KEY), OPENAI_API_KEY, ANTHROPIC_API_KEY | LLM provider (and RAG embeddings; Anthropic uses OPENAI_API_KEY for them) |
OLLAMA_URL (default http://localhost:11434), OLLAMA_API_KEY | Ollama, local or remote |
TG_TOKEN (or TELEGRAM_TOKEN), DISCORD_TOKEN | Telegram and Discord bots |
SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET, SLACK_APP_TOKEN, SLACK_PORT | Slack (Socket Mode with the app token, else HTTP mode on SLACK_PORT) |
WEBCHAT_TOKEN | WebChat client token (?token=); WebChat does not start without it |
DATABASE_URL / POSTGRES_URL | Postgres memory without memory.connectionString |
DEEPGRAM_API_KEY, GROQ_API_KEY, OPENAI_API_KEY | Voice message transcription, first one found wins (else local Whisper) |
TAVILY_API_KEY, BRAVE_API_KEY, SERPER_API_KEY | Web search |
GITHUB_TOKEN | GitHub tool |
cogitator up loads the .env next to cogitator.yml into process.env without overriding variables that are already set, so tools that read process.env when they run (web_search, github_api) see the keys the wizard wrote. With RuntimeBuilder in your own code, put those keys in process.env yourself — the builder's env argument is not copied there.