npl-runtime
v0.3.2
Published
Simple NLP runtime: intent + multi-turn slots + WhatsApp button/list interactive.
Readme
npl-runtime
Simple NLP for chatbots: match intent → ask slots (with WhatsApp list/buttons) → confirm → onComplete.
Install
npm install npl-runtimeQuick start (with WhatsApp network list)
import { createNplRuntime, type CompleteContext } from 'npl-runtime';
async function fetchNetworks() {
return ['mtn', 'airtel', 'glo', '9mobile']; // or hit your API
}
const npl = await createNplRuntime({
intents: [
{
name: 'buy_airtime',
examples: ['buy airtime', 'recharge', 'top up', 'vend'],
reply: 'Sure — I can help with airtime.',
slots: {
network: {
ask: 'Which network should I recharge?',
fetchOptions: async () => fetchNetworks(),
whatsapp: {
buttonText: 'Pick network',
sectionTitle: 'Available networks',
fetchItems: async () => fetchNetworks(),
},
},
amount: {
ask: 'How much?',
type: 'number',
min: 100,
max: 50000,
},
},
confirm: true,
onComplete: async ({ payload }: CompleteContext) => ({
ok: true,
message: `Purchased ${payload.amount} on ${payload.network}.`,
}),
},
],
});
const out = await npl.handle('I want to buy airtime', { sessionId: from });
// out.whatsapp: { type: 'list', body, buttonText, sectionTitle, items: [...] }
// ≤3 options → type: 'button' | 4+ → type: 'list'
if (out.whatsapp?.type === 'list') {
await sendList(from, {
body: out.whatsapp.body,
buttonText: out.whatsapp.buttonText!,
sections: [{
title: out.whatsapp.sectionTitle,
rows: out.whatsapp.items.map((i) => ({
id: i.id,
title: i.title,
description: i.description,
})),
}],
});
} else if (out.whatsapp?.type === 'button') {
await sendButtons(from, {
body: out.whatsapp.body,
buttons: out.whatsapp.items.map((i) => ({ id: i.id, title: i.title })),
});
} else {
await sendText(from, out.reply ?? '');
}When the user taps a list row, pass list_reply.id (e.g. "mtn") back into handle.
Slot WhatsApp config (like NPL-Xel)
network: {
ask: 'Which network?',
fetchOptions: fetchNetworks, // for validation
whatsapp: {
buttonText: 'Pick network',
sectionTitle: 'Available networks',
fetchItems: fetchNetworks, // for the interactive UI
},
}Or static:
choices: ['mtn', 'airtel', 'glo', '9mobile'],
// package still builds out.whatsapp from choices if whatsapp/fetchOptions omittedRule
| Options | out.whatsapp.type |
|---|---|
| 1–3 | button |
| 4–10 | list |
Optional LLM intent
intentModel: { provider: 'openai', model: 'gpt-4o-mini', apiKey: process.env.OPENAI_API_KEY }License
ISC
