x51 // @kung-fu // max
x51@cyberspace:~$ man max
MAX(3)@kung-fu Library Functions ManualMAX(3)
name
max — a minimalist chatbot framework that works like a true conversation
description
max models a chatbot as a loop of conversational turns rather than a tree of routes. A Bot listens, and each incoming turn flows through middleware to your handler, where the bot can say something, ask a question and remember the answer, or hand the turn to a scripted Dialog. State persists per user in a Memory backed by pluggable storage, and remembered values interpolate into replies with Handlebars-style templates.
Two bots ship with the framework: ConsoleBot runs the conversation on the command line; WebBot exposes it as an HTTP endpoint. Both extend the same abstract Bot, so a bot written against one runs on the other.
classes
| class | description |
Bot | abstract base: listen(), say(), ask(), hears(), use(), on() |
ConsoleBot / WebBot | command-line and HTTP-endpoint implementations |
Dialog | chainable sequence of ask / say exchanges |
DialogSequence | names and orders multiple dialogs |
Message | message content, attachments, and template interpolation |
Memory | per-user state as a Map; load() / save() against storage |
Middleware / HearMiddleware | turn-processing pipeline; phrase and regex matching |
CacheStorage | in-memory storage backend |
examples
A console bot that asks for your name once, then remembers it — remember stores the answer in Memory, and {{name}} interpolates it back:
const { ConsoleBot, CacheStorage, Memory, getTurn } = require('@kung-fu/max');
const bot = new ConsoleBot({ name: 'mybot', type: 'console' }, new CacheStorage());
bot.listen(async (conversation) => {
const turn = getTurn(conversation);
const memory = await new Memory(bot.storage).load();
if (memory.name === undefined) {
await bot.ask('What is your name?', { remember: 'name' });
} else {
await bot.say('Hello {{name}}, you said: ' + turn.message.text);
}
});
A scripted Dialog — the chain runs turn by turn until it completes, then the bot falls through to free conversation:
const dialog = new Dialog(bot)
.ask('What is your name?', { remember: 'name' })
.ask('Hi {{name}}, what is your age?', { remember: 'age' })
.say('Thank you {{name}}!');
bot.listen(async (conversation) => {
if (!await dialog.continue(conversation)) {
await bot.say('You said: ' + conversation.turn.message.text);
}
});
Pattern matching with hears() — phrases and regexes are checked automatically before your handler runs:
bot.hears('hello', async () => { await bot.say('Hi there!'); });
bot.hears(/^help/i, async () => { await bot.say('Available commands: help, quit'); });
Or skip remember and handle an answer yourself with a callback:
await bot.ask('Your name?', async (response) => {
memory.name = response;
await memory.save();
});
see also
@kung-fu2026-06-04MAX(3)
x51@cyberspace:~$ cd ~/@kung-fu █