Trevia Lab
A conversational assistant and content pipeline, designed and run solo
- Role
- Design, development, operations
- Team
- Solo
- Since
- 2026
Trevia Lab makes custom objects through laser engraving, laser cutting and 3D printing. I handle the whole technical and editorial side of it, alone, alongside my client work.
That constraint is interesting: no team to pick up after me, no budget to buy back an architecture mistake, and every line of code has to survive months without my touching it.
The conversational assistant
The site answers visitor questions through an assistant I built rather than a third-party widget, to keep control over both the answers and the costs.
Architecture. A Cloudflare Worker in TypeScript sits between the browser and the model API. The API key never leaves the server. The response stream is normalised in the Worker, which makes the widget provider-agnostic: switching models requires no client-side change.
Cost control. The corpus sent with each conversation is cached by the provider, which cuts the bill by three on subsequent exchanges. I measured the real cost per conversation before going live, rather than discovering it on the invoice.
Guardrails. Per-IP daily rate limiting, maximum message and conversation length, an allow-list of origins, and above all distinct error codes per cause. A spend cap being reached and a provider outage produce two different messages: without that, diagnosis takes an hour instead of a minute.
Controlled degradation. The corpus is served as plain text from the site. If the file disappears, the Worker falls back to the equivalent HTML page, with two checks that catch the case where the server returns an error page under a success status. Without them, the assistant would answer from an error page and nobody would notice before a visitor complained.
The content pipeline
Reference content exists in three forms generated from a single source: the public page, a lightweight text file for assistants, and a condensed corpus for the chatbot.
A Python script handles generation, with checks that halt the pipeline rather than publish a doubtful file: content boundaries not found, abnormal volume, forbidden phrasings, unsubstituted template markers. The exit code becomes 1 on any alert, which makes it usable in an automated pipeline.
The problem solved is not technical, it is human. Three files describing the same thing drift apart within weeks. Generating from a single source, plus an automated consistency check between versions, prevents that drift, which had already happened before they were in place.
The rest
Performance and accessibility. Fixing a library conflict where the theme overrode a version loaded upstream, conditional loading of animations, fixing an accordion ARIA error validated across several audit-engine versions, image optimisation to WebP.
Personal data. Privacy policy rewritten to cover the assistant: processors declared, no conversation retention, IP address retention limited to the rate-limiting window.
Catalogue. Prices and availability are read from the site API, never copied. A price frozen in a file always ends up wrong.
What the project demonstrates
- TypeScript
- Worker in strict TypeScript, two provider implementations behind a shared interface
- Edge computing
- Cloudflare Workers, platform limits identified and respected, key-value storage and quotas
- LLM integration
- Streaming, prompt caching, multi-provider normalisation, system-prompt engineering with a test suite
- Production reliability
- Distinct error codes, controlled degradation, spend caps, usable logging
- Automation
- Script-generated content with blocking checks and an exit code
- Front-end
- Library conflict resolution, conditional loading, accessibility, performance budget
- Compliance
- GDPR applied to a conversational service, processors and retention periods