Spaces:
Running
Running
| # ProcureMind (PR-AGENT) β Project overview | |
| This document describes **what this codebase is for**, **which technologies it uses**, and **how the pieces fit together**. It complements the short setup notes in the root `README.md`. | |
| --- | |
| ## 1. Purpose | |
| **ProcureMind** is a **procurement assistant demo**: a chat-style web app that helps users describe what they need in natural language, **match that need to a structured catalogue** (UNSPSC-style commodity codes), **fill in a dynamic form** for the chosen item, and **preview purchase requisition (PR) line items**. | |
| Typical user journey: | |
| 1. User describes a need (for example, office chairs or laptops) in the chat. | |
| 2. The backend uses an **LLM with tools** to search a **local SQLite catalogue** (full-text search). The model never invents codes; it only picks from tool results. | |
| 3. The UI may show **one best match**, **several candidates to choose from**, or **βnot foundβ** with guidance. | |
| 4. After a commodity is selected, the app loads or generates a **form schema** for that code, collects answers, and can **build PR rows** for review/export. | |
| It is aimed at **demos, pilots, and Hugging Face Spaces** β not a full enterprise procurement system (no ERP integration, approvals, or real vendor catalogs in this repo). | |
| --- | |
| ## 2. Technology stack | |
| | Layer | Technology | Role | | |
| |--------|------------|------| | |
| | **Frontend** | React 18, TypeScript | SPA: chat thread, cards, forms, tables | | |
| | **Frontend build** | Vite 5 | Dev server, HMR, production bundle | | |
| | **Styling** | Tailwind CSS 3, PostCSS, Autoprefixer | Layout and components | | |
| | **Backend** | Python 3.11, FastAPI, Uvicorn | JSON REST API under `/api` | | |
| | **AI** | OpenAI Python SDK (`openai`) | Chat completions + **function/tool calling** (default model configurable, often `gpt-4o-mini`) | | |
| | **Data / catalogue** | SQLite + **FTS5** (full-text index) | Searchable UNSPSC-derived catalogue | | |
| | **ETL** | Pandas, openpyxl | Build `unspsc.db` from Excel (`server/build_db.py`) | | |
| | **Production (Space / Docker)** | Docker multi-stage, **nginx** | Serves static React build; **reverse-proxies** `/api/` to Uvicorn on port 8000; listens on **7860** (Hugging Face convention) | | |
| **Environment:** `OPENAI_API_KEY` is required for real LLM behavior. Optional: `OPENAI_MODEL`, `UNSPSC_DB_PATH`, `UNSPSC_XLSX_PATH` (see README). | |
| --- | |
| ## 3. How it works (architecture) | |
| ### 3.1 High-level diagram | |
| ```text | |
| Browser (React) | |
| β HTTP: /api/chat, /api/form-schema/β¦, /api/build-pr | |
| βΌ | |
| FastAPI (server/main.py) | |
| βββ run_agent() β OpenAI + tools β search_catalog / get_commodity (SQLite) | |
| βββ get_or_create_schema() β form fields for commodity (may call OpenAI) | |
| βββ build_pr_rows() β structured PR line rows from form answers | |
| βΌ | |
| SQLite (data/unspsc.db) β built from data/unspsc-english*.xlsx | |
| ``` | |
| **Local development:** Vite proxies `/api` to `http://127.0.0.1:8000` (see `vite.config.ts`). | |
| **Docker / Hugging Face:** nginx serves the built SPA and forwards `/api/` to Uvicorn (see `nginx.conf`, `docker/start.sh`). | |
| ### 3.2 Main API surface (`server/main.py`) | |
| | Endpoint | Method | Purpose | | |
| |----------|--------|---------| | |
| | `/api/health` | GET | Liveness check | | |
| | `/api/chat` | POST | User message (and optional locked commodity code); returns JSON for UI (status, summary, candidates, analysis rows, errors) | | |
| | `/api/form-schema/{commodity_code}` | GET | JSON schema for dynamic procurement form for that code | | |
| | `/api/build-pr` | POST | Builds PR line rows from commodity code + dynamic field values + delivery options | | |
| ### 3.3 Agent (`server/agent.py`) | |
| - **System prompt** defines ProcureMind rules: search with short phrases, retry searches, return `found` / `choose` / `not_found`, never invent codes. | |
| - **Tools** expose catalogue operations (for example `search_catalog`, `get_commodity`) so the model reads the DB **only through defined functions**. | |
| - If `OPENAI_API_KEY` is missing, the API returns a structured error instead of calling OpenAI. | |
| ### 3.4 Catalogue (`server/catalog.py`, `server/build_db.py`) | |
| - Excel input follows a known UNSPSC export layout; `build_db` creates SQLite tables and an **FTS5** index for keyword search. | |
| - Runtime queries use FTS + helpers (tokenization, stopwords) so long user sentences are turned into searchable queries. | |
| ### 3.5 Frontend (`src/`) | |
| - **`App.tsx`** orchestrates chat state, thread items (analysis cards, disambiguation, forms), PR preview, and modals. | |
| - **`src/api/chat.ts`** and **`src/api/form.ts`** call the backend (optional `VITE_API_BASE` for non-default API origin). | |
| --- | |
| ## 4. Repository layout (short) | |
| | Path | Description | | |
| |------|-------------| | |
| | `src/` | React UI, components, API clients | | |
| | `server/` | FastAPI app, agent, catalog, form schema, PR lines, DB build | | |
| | `data/` | Source XLSX (LFS) and generated `unspsc.db` (after build) | | |
| | `docker/start.sh` | Starts Uvicorn + nginx in the container | | |
| | `Dockerfile` | Node build β Python runtime + nginx | | |
| | `nginx.conf` | SPA + `/api` proxy | | |
| --- | |
| ## 5. Related links | |
| - [Hugging Face Spaces config](https://huggingface.co/docs/hub/spaces-config-reference) (YAML in README frontmatter for the Space) | |
| --- | |
| *Generated for maintainers and onboarding; adjust as the product evolves.* | |