Enterprise-grade, responsible AI for facility maintenance, on Microsoft Foundry and the Microsoft Agent Framework.
Getting started · Architecture · Enterprise AI concepts · Screenshots
A 70-second walkthrough of the running app (synthetic data). More in Screenshots.
Tenants report maintenance problems by text, photo, voice note or scanned document. A deterministic pipeline screens, redacts, classifies and routes each request with AI, and keeps people in charge of anything dangerous or expensive.
The project is a worked, open-source example of the practices around AI that real companies need: guardrails, privacy, human oversight, evaluation, identity and access control. New to AI? Start with Enterprise AI concepts, which explains each one in plain words. All data in the repository is synthetic.
- Multimodal intake: text, photos (Azure AI Vision), voice notes (Azure AI Speech) and scanned documents (Azure AI Document Intelligence), in English, Spanish and French.
- Translation for staff: Spanish and French requests reach staff in English via Azure AI Translator, translated only after personal data is redacted, with the original one click away.
- Emergency bypass: gas, fire, carbon monoxide, electrical hazards or flooding go straight to an on-call person by local rules, before any AI; a tenant can also mark a report as an emergency, which skips every check.
- Guardrails: Content Safety on text and images, Prompt Shields against direct and hidden (in-document) prompt injection, upload checks by file bytes, structured model output, fail closed to a person.
- Privacy: personal data redacted before any model, log or trace; originals encrypted and revealable only to authorized roles, with every reveal audited.
- Human in the loop: uncertain or flagged requests go to a review queue; high-priority work needs approval.
- Identity and RBAC: Microsoft Entra ID (staff) and Entra External ID (resident sign-up); permissions checked on every API call, deny by default; no API keys anywhere.
- Evaluation: a synthetic golden set, fairness and injection tests, and an emergency-recall gate in CI.
- Transparency: a decision trail for every request (each check, its result and version), what the model was sent and answered, append-only audit logs, and structured logs correlated with traces.
- Observability: OpenTelemetry to Application Insights and agent monitoring dashboards.
How to read it. The animation follows one request through the system in 18 steps (about 70 seconds, then it repeats); a still version shows everything at once. Grey boxes are code, purple boxes are AI agents, amber boxes are people.
- Every request goes through a fixed pipeline in code (
IntakeCoordinator), where one AI agent, the classifier, only suggests a category and priority. Emergencies skip the AI entirely. - Escalated incidents (high-priority heating, electrical or plumbing) go to a team of seven agents. The Incident Manager agent plans and decides which specialist works next; six specialists each have read-only tools or knowledge, and all of them run within fixed budgets.
- No agent can act. The team proposes a plan with citations; a facility manager approves, revises or rejects it, and only then does the application carry out the approved actions.
The request flow in more detail:
flowchart LR
R[Request<br/>text · photo · voice · scan] --> E{Emergency<br/>screen}
E -- emergency --> H[On-call person<br/>no AI]
E -- with a file --> F[File checks · image safety<br/>read the file]
F --> P
E -- text --> P[PII redaction]
P --> S[Content Safety +<br/>Prompt Shields]
S --> C[Classifier agent]
C --> W[Work order /<br/>approval]
F & P & S & C -. failure or flagged .-> Q[Human review]
Details of the incident team (escalation, the event-driven worker, the seven agents, their read-only tools and knowledge base, plans and the approval gate): architecture and agent orchestration.
Two Microsoft products are involved, and they do different jobs:
- Microsoft Agent Framework is the open-source framework
the agents are written with: the agents themselves, their tools and middleware, and the Magentic orchestration in
which the Incident Manager plans and hands work to the specialists (
agents/team.py). - Microsoft Foundry hosts the models the agents call (gpt-5.2 for the manager, gpt-5.4-mini for the specialists), the Foundry IQ knowledge base and the evaluators.
Foundry Agent Service offers several ways to run agents: prompt agents defined in the portal, hosted agents (your own code, including Agent Framework code, run by Foundry as a container), or your own process calling the Responses API on the Foundry project endpoint, which Microsoft calls an ephemeral agent. This project uses the last one: the agents run in the incident worker and call Foundry for every model request, signed in with Entra ID. That choice keeps four things in the application:
| Kept in the application | Why it matters here |
|---|---|
| Every model call passes our middleware | Token, tool and time budgets are enforced in code, and each call is written to the decision trail |
| Tools read our database directly | Each facility tool runs in a READ ONLY PostgreSQL transaction, with no extra API to expose |
| No conversation stored by the service | Agents run with store: false, and they only ever see redacted text |
| One place to run and test | The same worker code runs locally, in the scripted test harness, and in Container Apps once deployed |
The trade-off: there's no agent to manage in the Foundry portal, and scaling the worker is ours to do. Because the team is plain Agent Framework code, it could later be packaged as a Foundry hosted agent without rewriting the orchestration; the database tools would then need a network path from Foundry's sandbox to PostgreSQL.
| Layer | Technology |
|---|---|
| AI | Microsoft Foundry, Microsoft Agent Framework, Azure AI Language, Content Safety, Vision, Speech, Document Intelligence, Translator |
| Backend | Python 3.13, FastAPI (ASGI), Connect RPC + protobuf, SQLAlchemy, Alembic, PostgreSQL |
| Frontend | React 19, TypeScript, Vite, Tailwind CSS, shadcn/ui, Connect-Web (gRPC-Web), TanStack Query |
| Identity | Microsoft Entra ID, Entra External ID, MSAL, managed identity |
| Operations | OpenTelemetry, Application Insights, Docker, GitHub Actions |
Prerequisites: Python 3.13+, PostgreSQL 16+, Node 24 and, for the AI steps, the Azure CLI. Install commands for macOS, Windows and Linux.
git clone https://github.com/wasif1024/facilityops.git && cd facilityops
cp .env.example .env # set DATABASE_URL; add Azure endpoints to enable the AI steps
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements-dev.txt
scripts/db.sh # create the database, apply migrations, create demo accounts
scripts/dev.sh # API + incident worker + web app → open http://localhost:5173Without Azure the app still runs; AI steps fail closed to the human-review queue. Docker, running each side separately, Azure setup and troubleshooting: Getting started.
The migrations create one demo account per role, so you can explore straight away. Locally there are no passwords: the app opens on Choose a demo account.
| Account | Role |
|---|---|
local-developer |
Administrator |
alice |
Tenant (normal user) |
fm |
Facility manager |
tech |
Technician |
Warning
Demo accounts are for learning only and work only in local development mode. Before using this project for
real, remove them with scripts/db.sh remove-demo-accounts (create your own administrator first). They are
never created when APP_ENV=production. Why and how.
azd up creates the Azure resources from infra/ (Bicep) and deploys the API, the incident worker and the
web app to Container Apps. Every service is reached with one managed identity: PostgreSQL with Entra sign-in and no
password, Service Bus for events, Key Vault for secrets. It reuses your existing AI Services and AI Search resources.
It creates paid resources (roughly $60–75 a month before model usage): read Deploying to Azure
first.
The project applies Microsoft's six Responsible AI principles:
| Principle | In this project |
|---|---|
| Fairness | Counterfactual tests: the same request with a different name, language or building must be routed the same |
| Reliability and safety | Emergency bypass, fail closed, human approval, emergency-recall gate on every pull request |
| Privacy and security | Redaction before AI, encrypted role-gated reveal, no stored media, no API keys, deny-by-default access |
| Inclusiveness | Three languages; report by voice or photo; works on a phone |
| Transparency | A "Why this decision" trail for every request, the exact model input and answer, published metrics and known limitations in the transparency note |
| Accountability | People approve risky actions; every decision and data reveal is audited |
The Responsible AI transparency note sets out what the AI does and doesn't do, how well it works, its known limitations and how people stay in control.
| Metric | Result (gpt-5.2) |
|---|---|
| Emergency recall (CI gate, must be 1.00) | 1.00 |
| Emergency screen on held-out phrasings in EN/ES/FR, before → after extending the rules | 0.37 → 1.00 (not independent) |
| Category accuracy | 0.91 |
| Prompt-injection resistance | 1.00 |
| Counterfactual fairness (routes) | 1.00 |
| Photo and scanned-document cases (live) | 6/6 |
108 synthetic golden cases plus a live media eval. Method, all metrics and how to run them: specification §10.
| Document | Contents |
|---|---|
| Getting started | Installation, running locally, demo accounts, Azure setup |
| Enterprise AI concepts | Each enterprise and Responsible AI concept, explained for newcomers |
| Architecture | System, orchestration tiers, multi-agent design, trust boundaries |
| Specification | Requirements, guardrails, privacy, evaluation targets |
| Developer commands | Every command: database, backend, frontend, tests, evals, troubleshooting |
| Identity setup | Entra External ID for residents, workforce Entra ID for staff |
| Deploying to Azure | azd up: what is created and why, roles, steps, cost, removal |
| Responsible AI transparency note | Intended uses, safeguards, performance, known limitations |
| Frontend specification | Screens per role, API usage, accessibility |
| Screenshots | Every workspace: tenant, facility manager, technician, administrator |
backend/ Python API: domain logic, Azure adapters, RPC handlers, migrations, tests
frontend/ React web app
proto/ API contracts (protobuf)
evals/ golden set and evaluation runners
infra/ Azure infrastructure (Bicep) for azd, with its hooks
scripts/ db.sh (database), dev.sh (run locally), setup scripts
docs/ documentation and diagrams
Everything above is built and tested. These are natural next steps; the first three are ready to run but use paid Azure resources, so they are left to whoever deploys the project:
- Deploy to Azure with
azd up(deployment guide); the templates are validated, not yet deployed. - Run the live incident evaluation (
python -m evals.run_incident_scenarios --mode live --store): Foundry's Groundedness and Tool Call Accuracy evaluators on the real team, targets ≥ 0.90. - Red-team scan with the Azure AI Red Teaming Agent (PyRIT), and publish the report.
- Resume a paused incident run from a checkpoint; today a revision starts a new run with the manager's feedback and the previous plan.
Known limitations are listed in the transparency note.
FacilityOps AI was designed and built in October 2026 by wasif1024, with an AI coding assistant (Claude Code) as a pair programmer. The author set the goals and requirements, made the design and trade-off decisions, and reviewed the work; the assistant wrote most of the code, tests and documentation under that direction. The results in this README come from tests and measured runs, and the limits are stated as plainly as the results (transparency note). Building a system like this with an AI assistant, while keeping it tested, honest about its gaps and safe by design, is part of what the project demonstrates.
Issues and pull requests are welcome. Please run the tests (python -m pytest -q backend/tests/unit,
cd frontend && npm run test) and keep all data synthetic: no real names, addresses or documents.
Released under the MIT License. You are free to use, modify and distribute this project, including commercially, provided the copyright notice is kept.
