AI Council Assistant
Ask a planning question in plain English and get an answer drawn from published Cork County Council documents — with the documents it used listed underneath, so you can check it rather than take its word.
Which Cork? County Cork in Munster, the largest and southernmost county of Ireland, with a population of about 584,000. It is administered by Cork County Council — a separate authority from Cork City Council, which governs the city itself. This demonstration covers the county council's planning material only.
Try it
Open the Ask Planning button in the corner. Every substantive answer ends with a Sources list naming the documents and page ranges it drew on. Questions that work well:
Where can I find short-term letting guidance?
How do I apply for planning permission?
What is a Section 5 declaration of exemption?
You can also dictate a question with the microphone, or carry the conversation into WhatsApp or Telegram using the buttons beside Send — the same assistant answers on all three.
What it is demonstrating
That a public-sector information service can be answered conversationally without the assistant inventing anything. The interesting part is not the chat — it is the discipline behind it:
- Every answer shows its sources. Document title, page range and a link to the original PDF on
corkcoco.ie. - It declines rather than guesses. Asked something the prepared documents do not cover, it says so instead of producing plausible-sounding text.
- It is anonymous. No login, no contact details, no profile, no personalisation. Your question is not tied to an identity.
- It sells nothing. There is no catalogue, cart or payment anywhere in this tenant — unusual for the platform it runs on, and deliberate.
Where the content comes from
The Council's Planning and Development section covers a great deal — the County Development Plan, public consultations, weekly lists, the Residential Zoned Land Tax, development contributions and more. This demonstration deliberately takes one part of it: Planning Information, Leaflets & Forms. A narrow, verifiable slice is more useful than a broad one nobody has checked.
Within that slice the corpus was assembled by hand: published information pages, guidance leaflets, blank forms and circulars. Nothing was crawled — each document was opened, read and selected, and the ones that were rejected are recorded too.
What was deliberately left out
- Individual planning applications, submissions and correspondence, and anything naming an applicant.
- Completed forms — only blank ones are included.
- Other Council departments, and Cork City Council, which is a separate authority.
- Material whose current edition could not be established. Where two versions of a document exist, both are kept and labelled rather than one being guessed at.
What it cannot do
It does not accept applications, check the status of a case, look anything up about a specific address or applicant, decide whether something is exempt, or take a payment. For anything official, use the Council's own channels — the assistant says the same when asked.
Planning law and fees change. Answers reflect the documents as captured, and the source list is there so you can open the original and check its date.
How an answer is produced
- The question is turned into a vector and matched against the indexed passages.
- The passages that match, and only those, are given to a language model as the material it may use.
- The answer is assembled with the source metadata of the passages behind it. If nothing relevant was retrieved, it declines instead of answering.
Document selection and chunking were done ahead of time as a reviewed package, not at request time — which is why a passage can name its page range, and why adding a document is a deliberate act rather than a side effect.
The stack, and why each part is there
This runs as one tenant on AIFA, an event-driven micro-service platform that also serves retail and hospitality tenants. Nothing here is bespoke to Cork except the corpus and the answer policy — which is the point: a new public-sector assistant is a configuration and a reviewed document package, not a new system to maintain.
| Drupal |
Because corkcoco.ie is a Drupal site. The assistant is
delivered as a single <script> tag a content editor can
paste into a page — no module to install, no theme to change, no build step,
no npm. It brings its own styles so it cannot disturb the site's layout, and
it is pinned to an allowlisted origin so the key in the page cannot be
reused elsewhere.
|
|---|---|
| AIFA engine | Provides the parts that are the same for every assistant: the conversation runtime, the channel bindings that let one tenant answer on web and Telegram at once, tenant isolation, and an event bus so services do not call each other directly. Reused rather than rebuilt. |
| Prepared corpus | Documents are selected, split and validated before deployment, as a reviewed package with a manifest. That is what lets an answer name a document and a page range, and it makes adding a document a deliberate act with a record, rather than something a crawler did. |
| Qdrant | Vector search over those passages, with each tenant's content isolated. This is what finds the right passages for a question. |
OpenAI text-embedding-3-small |
Turns the question and the passages into comparable vectors so the search works on meaning rather than keywords. It never sees a whole document at answer time. |
openai/gpt-oss-20b on Groq |
Phrases the answer from the passages that were retrieved — and only those. It is used for wording, not as a source of facts, which is why the assistant can decline when the corpus has nothing relevant. |
| Web Speech API | Voice input using the browser's own recogniser, so no audio is uploaded anywhere and there is no dependency to pay for. Shown only in browsers that support it, rather than failing on click. |
| Python, FastAPI, RabbitMQ, PostgreSQL, Docker Compose | What it actually runs on: a single modest Linux host, deployed by rebuilding the affected services one at a time and verifying each reports the expected revision before moving on. |
One tenant of a platform
The point of building this on AIFA rather than as a standalone site is that the hard parts are shared. The same runtime, channel layer and deployment serve tenants doing quite different jobs — each with its own catalogue or corpus, its own answer policy, and its own channels:
- Fashion store — search, styling advice, sizes, cart and checkout
- Boutique hotel — rooms, availability, booking, and a regional guide
- Fashion retailer — a real catalogue of 700+ items, two languages, two markets
- Digital gift cards — regional catalogue, mobile top-ups, instant code delivery
- This assistant — no catalogue, no cart, no payment; it answers from documents and cites them
That last line is the interesting one. Adding a tenant that sells nothing meant the platform had to stop assuming every tenant has a catalogue — which is the sort of change a demonstration is for.
What it had to respect to live on a Council site
A corporate Council site is a governed, regulated platform, not a blank page. Those constraints shaped the build more than any feature did:
| Survives Drupal upgrades | No custom module and no theme override, so there is nothing of ours to break when Drupal core or contributed modules are updated, and nothing to re-test on a 9 → 10 → 11 migration. It is a script tag in a content block; if it were ever removed, the page it sits on is unchanged. |
|---|---|
| Content governance | Adding or removing a document is a change to a reviewed corpus package with a manifest and a validation report — not an edit anyone can make invisibly. The assistant answers only from what that package contains. |
| Accessibility |
Semantic HTML with labelled controls, text that scales with the browser, and
a layout that works down to phone width. Checked with axe-core
against this page with the chat both closed and open: no violations reported.
Automated checks are a floor, not a certificate — a full WCAG audit against
the 2020 Regulations would still be its own piece of work.
|
| Performance |
One async script, about 28 KB, no framework, no build
output, no web fonts and no external stylesheet. It cannot block rendering or
move the host page's layout, so it does not put the site's own performance
budget at risk.
|
| Data protection | No login, no contact details, no profile, no tracking. Voice input is transcribed by the browser itself, so no audio is uploaded anywhere. Under GDPR the lightest position is not to collect in the first place. |
| Security | The key in the page is publishable and pinned to an allowlisted origin, so it is useless if copied elsewhere; a secret key never reaches the browser. The widget adds no inline event handlers and writes no cookies. |
| Plain English | The point of the assistant is to answer a plainly-asked question from formal planning documents — and then show which documents, so the reader can go to the source rather than trust the paraphrase. |
Embedding it elsewhere
The widget is one script tag; it needs no build step and carries its own styles, so it can sit on a Drupal page without touching the theme:
<script src="https://cork.aifa-demo.com/loader.js"
data-aifa-api-url="https://api.aifa-demo.com/v1/assistant/messages"
data-aifa-api-key="aifa_pk_cork_dev"
async></script>