Lankaink.

Documentation

How Lanka Link works

The customer app, the agent console, the admin area and the simulation, and what happens between a customer opening a ticket and reading the reply.

Overview

Lanka Link is a telecom operator with a support system that reads every request against the customer's own line, account and area before anyone replies. It runs as a set of services behind one address, http://localhost:8080.

  • /app: customers. Home, tickets, billing, usage, plan and settings.
  • /console: agents and leads. The queue, the draft, approve or send back.
  • /admin: admins. Auto reply, models, grounding plan, traces, feedback and users.
  • /sim: operators. The simulated network, incidents, customers and a test lab.

For customers

Support works as tickets. A ticket has a subject, a category and a thread. Customers can attach photos of the router and voice notes, and reply on the same ticket as often as they need. A reply on a closed ticket reopens it.

When something on our side affects them, the ticket shows it as a notice: repair work in the area with its estimate, a paused service with the amount to pay, planned maintenance with its window, busy evening hours, or a used up data allowance. These appear before anyone has to write back.

Past tickets are shown as a timeline. Answered and closed tickets ask for a rating from one to five and an optional comment, which admins see under feedback.

How a ticket flows

  1. Intake stores the message and attachments and opens or revises a case.
  2. In parallel: translation to English, speech to text, photo analysis and an account prefetch.
  3. Triage routes to a department by rules and scores the request with the TriageModel.
  4. Diagnosis retrieves procedures and names a likely fault.
  5. Grounding assembles the one bundle of facts the writer may use, and scores our side.
  6. Response drafts from that bundle only, checks every sentence, then releases or holds for an agent.

Each stage has a time budget. A late stage marks the case as partial rather than holding it up.

Two priorities

Every case carries two separate priorities on the one to ten scale.

  • Customer side, from the distilled TriageModel: a MiniLM embedding of the request plus eighteen engineered signals (urgency words, sentiment, repeat contact, photos, error codes, account segment and service level age). It predicts an urgency band and a score.
  • Our side, from rules over the account and network records: an open outage, a line our equipment cannot see, a barred account, an unusual charge, maintenance, congestion. The worst finding sets the level, raised for service tier and service level risk.

The queue sorts by the higher of the two. The console shows both, each with its reasons.

How replies are written

The writer sees one bundle and nothing else. Replies open with the customer's own side(a loose cable, a red light, the Wi-Fi) with steps taken only from the device guidance and procedures, then cover anything on our side in a separate paragraph, because fixing one side alone may not restore the service. No amount, date or step is ever invented.

Every sentence is checked as it streams: no refund promises, no guarantees, no personal data, no actions the customer is not entitled to. One failed check holds the reply for an agent.

For agents

The console queue lists cases by priority with both sides shown. A case shows what the customer sent, what we found, why it has its priority, and the draft. Agents approve, edit, send back or escalate. Ctrl K finds any case.

For admins

  • Auto reply: per department, whether a clean, low priority draft may go out without review.
  • Models: swap the drafting and diagnosis models live (Ollama, Gemini, or the offline stand in) and probe them.
  • Grounding plan: which facts each department checks, with a dry run against a real customer.
  • Traces: every stage of every case with timings, and the bundle the writer saw.
  • Feedback: average rating and the latest comments, on the overview.

The simulation

The business behind the app is simulated: exchanges, OLTs, lines, routers, invoices and usage move on a sim clock you can pause, speed up or jump forward. The panel is split in two:

  • Network: the live topology. Click equipment to open an outage, congest it or schedule maintenance.
  • Incidents: network scenarios and customer scenarios, and the board of active faults to clear.
  • Customers: accounts, line charts and customer scenarios such as a suspension or a crashing router.
  • Test lab: send a message as any customer and watch every stage live.

Models and retraining

The TriageModel lives in TriageModel/: a labelled corpus, an LLM labelling pass and a distilled multi task head. The triage service runs its exported numpy weights, so it needs no torch.

Retraining is a DVC pipeline (train, export, evaluate) driven weekly by an Airflow DAG. Every run is logged to MLflow. A candidate that beats the production model on the gold set, inside the latency budget, is promoted into the shared model volume and the triage service reloads it without a restart.

docker compose --profile mlops up -d      # MLflow on :5000, Airflow on :8081
cd ml && dvc repro                        # the same pipeline by hand

Tracing

With LANGSMITH_TRACING=true and a key, each case revision is one LangSmith trace: every pipeline stage nests under it with its inputs and outputs, and the draft appears as an LLM run with the exact prompt the writer saw.

Running it

cp .env.example .env              # NEON_KEY, BETTER_AUTH_SECRET, optional keys
docker compose up -d --wait        # everything
docker compose -f compose.yaml -f compose.lite.yaml up -d --wait   # every stage, translation and speech included
uv run python scripts/demo_flow.py # the headline case end to end

Seeded logins: agent1, lead1, admin1 and operator1 at lankalink.example.lk for staff, and eight customers at customers.lankalink.example.lk. See the plans to sign up as a new one.