An AI chat inside the app
The chat of the recipe, over the record it is about. The component, the streaming client and the context the page sends are the real ones; only the model's answer is deterministic and runs in the browser, which is why this page needs no API key.
Order #1043
Ada Lovelace
- Customer
- Ada Lovelace
- Status
- Shipped
- Total
- $32.90
- Placed
- September 1, 2026
Ask anything about this order — where it is, when it arrives, what it cost.
app/api/chat/route.go
// app/api/chat/route.go
func POST(c *trilha.Ctx) error {
who := AIChatWho(c)
if ok, after := AIChatLimit.Allow(who); !ok {
c.Header("Retry-After", strconv.Itoa(after))
return trilha.Errorf(http.StatusTooManyRequests, "too many questions")
}
c.Audit("ai.chat.asked", who)
return ai.ServeOpts{
HTML: ui.ChatHTML,
Context: AIChatContext,
Page: AIChatAnswerPage,
}.Serve(c, AIChatClient, AIChatAgent())
}
// the page
ui.Chat(c, ui.ChatOpts{
Action: "/api/chat",
History: AIChatLog.Read(AIChatWho(c)),
Context: map[string]string{"order_id": o.ID},
})
ui.ChatScript(c)What is pretending
Only the answer. There is no server behind this page: the documentation site is static, and the script answers the same events ai.Serve emits. In an application the form also works with JavaScript off — the same route answers the whole thing at once and the page comes back with the answer in it.