Overview
Billie for Construction — Translated
The Warehouse Assistant adapts IKEA's Billie multi-agent architecture — intent classification, confidence routing, RAG, and human handoff — for a commercial construction warehouse embedded in FieldOps alongside Procure and Contracts Q&A.
Where Billie routes retail queries (order tracking, product availability, billing problems), the Warehouse Assistant routes construction queries: material stock checks against IFC takeoff quantities, delivery status from PO records, receiving confirmations, damage reports with photo capture, invoice discrepancy flags, and specification lookups via pgvector RAG.
voice-engines/shared/claudeApi.ts helperuseAssistantStore) subscribing to activeUpload cross-module store for live IFC takeoff datajob_id to match FieldOps's existing 16-table schema conventionIntent Classification
Seven Intents — One Router
Every message from a field crew member is first classified by Claude into one of seven warehouse intents. The intent determines which specialist agent handles the response and what data source it queries.
| material_stock_check | Queries takeoff_line_items (required qty) minus installation_log (consumed) minus receiving_ledger in-transit. Returns the real on-hand gap — not a flat inventory count. |
| delivery_status | Queries PO records from the Procure module (status: issued|received) and shipment tracking data for ETA and dock appointment. |
| receiving_confirm | Writes a receiving confirmation entry to receiving_ledger. Field crew confirms quantity, condition, and PO match — with photo capture from FieldOps's existing capture pipeline. |
| damage_report | Initiates a damaged/short shipment report linked to the relevant PO line item. Routes to the safety override path if safety keywords are detected. Photo evidence attached via FieldOps capture hooks. |
| invoice_discrepancy | Flags a 3-way match failure: PO value vs. receiving confirmation vs. vendor invoice. Logs the discrepancy to the project record and optionally routes to procurement for resolution. |
| spec_lookup | RAG query against kb_chunks (pgvector, cosine similarity) over uploaded spec sheets, SDS documents, submittals, and vendor catalogs. Returns cited passages with source reference. |
| human_agent | Terminal intent — issued when confidence is below 60% or a safety override fires. Packages conversation context into a handoff summary card for a human supervisor to pick up. |
Confidence Routing
Three Bands. One Safety Override.
After intent classification, the confidence score routes the query to one of three paths. A separate safety override gate runs before the confidence check — if triggered, it bypasses all confidence bands and escalates immediately.
Before any confidence check runs, safetyOverride.ts scans the raw query for keywords including injury, unsafe, exposed wiring, structural, collapse. If any match, the query escalates immediately to a human agent — the EscalationBanner renders as a non-dismissible red banner in the chat UI. Confidence score is irrelevant: a "material_stock_check" flagged with a safety keyword escalates the same as a "damage_report". This is the key deviation from Billie's architecture, where escalation is sentiment-driven only.
- Safety override fires before any confidence check — no routing band can catch it first
- EscalationBanner is non-dismissible — requires explicit supervisor acknowledgment
- Damage reports near safety keywords auto-escalate regardless of how the intent was classified
- Override keywords are configurable per project in the assistant settings
Material Stock Check
Real Quantities — Not a Flat SKU Table
The critical deviation from Billie's product availability intent: stock check doesn't query an isolated inventory table keyed by SKU. In a construction warehouse, quantities are defined by the IFC takeoff — what's required to build the model. The warehouse assistant resolves against that published takeoff data, joined against what's arrived and what's been installed.
in_transit = receiving_ledger -- confirmed PO deliveries not yet consumed
installed = installation_log -- field crew confirms material consumed on-site
on_hand_gap = required − installed − in_transit
-- positive gap = material still needed
-- zero or negative = covered by deliveries + installed
The Publish to Warehouse action on the IFC Takeoff-Cost module is the upstream dependency — it writes finalized line items to takeoff_line_items in Supabase when a takeoff is committed. Until that action exists, material stock check runs against mock data behind the same service-layer seam used by Procure and Contracts Q&A.
- Required quantities sourced from IFC element GUIDs — full traceability to the BIM model element
- Supabase Realtime on
takeoff_line_items— warehouse updates live if a takeoff is republished - Receiving ledger fed by Procure module PO status (
status: received) — no duplicate data entry - Installation log entries created by field crew in FieldOps, same voice/photo capture pipeline
Knowledge Base
Spec Sheets, SDS & Submittals — AI-Searchable
The spec_lookup intent routes to a RAG pipeline over pgvector on Supabase — the same database already running FieldOps and Procure. No additional vector database vendor. Cosine similarity retrieval with project-scoped RLS so crews only see documents relevant to their job.
Document types supported
- Specification sections (CSI MasterFormat divisions)
- Safety Data Sheets (SDS) for all site materials
- Submittal packages — shop drawings, product data, samples
- Vendor catalogs and cut sheets
- Installation manuals and technical bulletins
Retrieval design
- Voyage AI embeddings (1024-dim) — Anthropic's recommended embedding partner
- Cosine similarity via Supabase
match_documentsRPC - Row-Level Security scoped by
project_id— no cross-job document leakage - Every answer cites the source document title and chunk reference
Database Schema
Five New Tables — Same Supabase Project
All new tables key on job_id to match FieldOps's existing 16-table schema convention. No project_id — job is already the project-equivalent in the existing schema.
FieldOps Integration
Scaffold — Same Pattern as Procure & Contracts Q&A
The Warehouse Assistant follows the same hub-page + dark sub-container pattern established by Procure and Contracts Q&A. Scoped CSS prefix (wa-*) prevents class collisions. Nav entry added to nav.ts. Route added to App.tsx.
├── src/features/warehouseAssistant/
│ ├── components/
│ │ ├── ChatWidget.tsx orchestrates intent → confidence → agent → response
│ │ ├── ClarificationPrompt.tsx rendered in chat for 60–90% confidence queries
│ │ ├── EscalationBanner.tsx red, non-dismissible — fires on safety override
│ │ └── HandoffSummaryCard.tsx packages context for human supervisor pickup
│ ├── agents/
│ │ ├── intentRouter.ts classify → {intent, confidence} via Claude
│ │ ├── confidenceRouter.ts >90 auto / 60–90 clarify / <60 human handoff
│ │ └── safetyOverride.ts keyword gate — bypasses confidence entirely
│ ├── api/ mock-backed, Supabase seam clearly marked
│ │ ├── materialStock.ts reads activeUpload takeoff store → on-hand gap
│ │ ├── deliveryStatus.ts Procure PO / shipment records
│ │ ├── receivingLedger.ts writes confirmation entries, reuses photo capture
│ │ └── knowledgeBase.ts pgvector cosine similarity via match_documents RPC
│ ├── store/
│ │ └── assistantStore.ts Zustand slice, subscribes to activeUpload cross-module store
│ └── types/index.ts WarehouseIntent union, message types, store shape
├── WarehousePage.tsx hub page — follows ProcurePage / ContractsPage pattern
├── WarehouseShell.tsx tab nav: Assistant | Stock | Receiving | Documents
└── warehouse.css wa-* scoped, self-contained — no procura.css dependency
Build Sequence
What's Built vs. What's Next
takeoff_line_items in Supabase. This is the upstream bottleneck — material stock check has nothing real to query until this exists.match_documents RPC, configure Voyage AI embedding generation on document upload. knowledgeBase.ts already has the retrieval call written.Module Status
Frontend scaffold complete — backend pending Supabase provisioning
The Warehouse Assistant runs today against mock data. Real stock checks activate once the Publish to Warehouse action is built in the Takeoff-Cost module.