KG

← Work

Meard Kairi

Next.js TypeScript SSE LLM guardrails Vitest

Streaming AI mentor inside NST's live open-source tracker. Guardrails sit outside the model: retrieved data is fenced from instructions and a 64-char holdback scans every SSE chunk for secrets.

Live (opens in new tab) Code (opens in new tab)

Problem

NST’s open-source tracker ranks students by merged pull requests, but a new contributor had nowhere to ask what a flag meant, which issue to pick, or how a repo fits together. A hosted model could answer, yet it would read GitHub profiles, issues and repo pages that anyone can edit. The real risk was prompt injection and secret leakage, not answer quality.

Approach

Kairi is a read-only agent at /kairi, built in Next.js and TypeScript. Sign-in uses GitHub OAuth with the read:user scope only, so writes are impossible rather than refused. A fixed registry of tools looks up standing, flags, issues and repository docs; nothing else is callable. Answers stream over Server-Sent Events as articles, each tool shown as it runs; refusals are plain JSON sent before the stream opens.

The guardrails sit outside the model, so they cannot be argued with. Retrieved GitHub and site data is wrapped in <retrieved_data> delimiters that the system prompt labels untrusted, never instructions. On the way out, guardStream scans the reply for token prefixes, config names and prompt echo, holding back 64 characters behind every released event so a secret split across SSE chunks never partially escapes. A match cancels the upstream and writes an audit event. Input screening strips invisible Unicode before any provider call, and spend caps reserve budget up front.

Result

Landed upstream across PRs #51, #52 and #55, with Vitest coverage of the adversarial cases, including split-token termination. Kairi runs on the college’s Kubernetes cluster at oss-tracker.nstsdc.org, behind rate limits, security headers and secret scanning shipped earlier in the series.