TypeScript · Messages API, no framework · long memory · escalation guardrail

Alagà · Guest AI Agent

It knows the whole stay and it acts with real tools. Anything a guest could get hurt by goes to a person.

status live run + 4 real appsrole designed + built end to end
Alagà · Guest AI Agent: Guest Ops on n8n: the workflow the agent fires. One guest event lands in the log
Guest Ops on n8n: the workflow the agent fires. One guest event lands in the log, then fans out to Slack, Gmail, Airtable, and Google Calendar in the same run.
recorded runlive
The raw run, then the actual receipts it produced across four apps. 35 seconds.
interactive · click and scroll itlive
The guardrail's full labeled set, all seventeen messages, plus the bug its tests caught on their first run: blood matched, bleeding did not.
10 + 7labeled messages in the guardrail's test set: ten that must force-escalate across four classes, seven ordinary ones that must not.
0questions re-asked. Wifi and check-out came out of stay memory, not out of the guest.
4 appsSlack, Gmail, Airtable, and Google Calendar written in one n8n run, from one escalation.
4 classessafety, money, legal, access. Screened before the model and checked again after it answers.
What it solves

Hospitality operators answer the same stay questions all day, then get woken at 2am by the few that actually need them. An agent that re-asks what it already knows is worse than a form. An agent that improvises on a refund or a gas leak is a liability. Alagà takes the repeat traffic and routes the rest to a person on purpose. The guardrail now has tests, and they failed on their first run: the rule matched the word blood but not bleeding, so a message about a bleeding child reached the model with no forced escalation. That is the exact case the guardrail exists for. Fixed, and the test is verified load-bearing by stubbing the escalation branch and watching it fail.

The constraint

Trust could not depend on the model. A guest agent is judged on its worst message, not its average one, so any rule that lived in the prompt was worth nothing. It also had to run for a stranger with no accounts and no setup, which put memory in a local SQLite file the repo carries with it, on Node's built-in driver so there is nothing to compile.

Who it serves

Short-stay and hospitality operators who want a guest-facing agent without handing it judgment calls.

Who it is for

Written to a founding-engineer bar: useful and safe at the same time.

How it works
  1. One guest messageThe agent loads the whole stay from memory, not just the last line, so it never re-asks what it knows.
  2. The guardrail runs firstAnything about money, safety, or legal is force-escalated in code before the model can answer, and backstopped after.
  3. The model actsFor everything else it uses real tools that do work, not 'I'll let the host know'.
  4. It fires a real workflowThe decision hits an n8n 'Guest Ops' flow that writes to Slack, Gmail, Google Calendar, and Airtable in one run.
The decision that was not obvious

The guardrail screens the same message twice. Before the model, which is the obvious half, and again after it has written its reply, which is not. A model that has already produced a warm, confident answer about a refund will not volunteer that it should have escalated instead. So the second pass ignores the reply completely and re-checks the original guest message. If a rule fired and the model did not escalate, the escalation is added anyway. The rules also hand back a holding line, which is why the gas-smell reply carries an actual safety instruction and the host's phone number instead of 'someone will contact you'.

What I would change if I rebuilt it today

Memory is per-stay and local. I would add a retrieval layer over property knowledge, the runbook-rag pattern with citations and refusal included, so the agent answers house questions from documents instead of facts stuffed into a prompt.

Built with
TypeScript Anthropic SDK (Messages API) node:sqlite memory tool-use loop n8n dispatch Slack · Gmail · Calendar · Airtable