Spaces:
Runtime error
Runtime error
| # PLAN - Worcestershire Libraries Live Assistant | |
| The blueprint for the build: what it is, how it's wired, what's done, and what's next. | |
| Companion docs: [README](README.md) Β· [SUBMISSION](SUBMISSION.md) Β· [IDEAS](IDEAS.md) Β· [FIELD_NOTES](FIELD_NOTES.md). | |
| ## Goal | |
| Give Worcestershire Libraries one conversational voice that answers any resident | |
| question from **official, source-cited data at every granularity** - down to | |
| *which branch has the copy on its shelf right now* and *exactly what every page | |
| of the Hive offers* - tells them **exactly what they need to sign up**, and | |
| **surfaces the services they never knew existed** - on a β€32B model, | |
| locally-capable. The DCMS-evidenced answer to "the library doesn't shout about | |
| what it offers." Built with/for Jack's library-resources team. | |
| The granularity ladder: | |
| | Level | Data | Tool | | |
| |---|---|---| | |
| | Service | 87 council service pages, eligibility-first | KB tools | | |
| | Page | all 57 pages of thehiveworcester.org, exact offerings + provenance | `hive_info` | | |
| | Item | live catalogue (Atom feed), incl. BorrowBox deep links | `search_catalogue` | | |
| | Copy | per-branch holdings + status from the item's detail page | `where_to_get` | | |
| ## Architecture | |
| ``` | |
| βββββββββββββββββββββββββββββββββββββββββββ | |
| user question βββΆ β route() LLM JSON router + keyword β | |
| β fallback (no-token safe) β | |
| βββββββββββββββββ¬βββββββββββββββββββββββββββββ | |
| βΌ | |
| βββββββββββββββββ 12 tools ββββββββββββββββββ βββ GraphRAG βββ | |
| β where_to_get (copy-level: shelf @ β β local_search β | |
| β branch β reserve β β β global_searchβ | |
| β BorrowBox tonight) β β multi-hop β | |
| β hive_info (57 Hive pages, exact βββββ over graph β | |
| β offer + provenance) β ββββββββββββββββ | |
| β search_catalogue (SirsiDynix Atom feed) β library_graph.json | |
| β whats_new (newest titles) β 349 nodes/502 edges | |
| β find_library (hours/open-now/facils) β incl. 26 HiveService | |
| β mobile_library (154 villages) β | |
| β library_events (live events) β | |
| β online_hub (PressReader/BorrowBoxβ¦)β | |
| β libraries_unlocked Β· printing Β· membership β | |
| βββββββββββββββββββββ¬βββββββββββββββββββββββββ | |
| βΌ | |
| synthesise (β€32B) + eligibility + Β£-receipt + EAST nudge | |
| + source link + open agent trace | |
| βΌ | |
| answer + quick-reply chips | |
| ``` | |
| ## Components & files | |
| | Layer | File | Role | | |
| |---|---|---| | |
| | Ingestion | `build_kb.py` β `library_kb.json` | Crawl all 218 library URLs β 87 services / 23 branches / 17 resources, with eligibility & facilities | | |
| | Hive ingestion | `build_hive_kb.py` β `hive_kb.json` | Crawl all 57 Hive pages β exact per-page offerings, what-you-need, prices, levels; curated `hive_profile` of 26 extended capabilities, every fact source-tagged | | |
| | Graph | `graph_build.py` β `library_graph.json` | Deterministic GraphRAG over BOTH KBs: entities β relationships β communities β reports (incl. 26 HiveService nodes; offline rebuild keeps villages) | | |
| | Sources | `library_sources.py` | 12 live/KB tools + curated hub access + membership tiers + copy-level availability parser | | |
| | Retrieval | `graph_rag.py` | local/global graph search (multi-hop) | | |
| | Traces | `trace.py` β `traces.jsonl` | per-turn structured agent trace (Open Trace badge) | | |
| | App | `app.py` | router, renders, behaviour-change layer, Gradio UI | | |
| | Custom UI | `server.py` + `index.html` | `gradio.Server` custom frontend (Off-Brand badge) | | |
| ## Build phases | |
| - [x] **P1 - Live tools.** Catalogue (Atom), mobile, events, printing. Verified live. | |
| - [x] **P2 - Comprehensive KB.** Full council-site crawl; eligibility + facilities + hours. | |
| - [x] **P3 - New tools.** find_library (open-now), online_hub (+curated access), libraries_unlocked, membership_help, whats_new. | |
| - [x] **P4 - GraphRAG.** 320-node graph; multi-hop "late library + cafΓ© + meeting rooms" β Malvern. | |
| - [x] **P5 - Behaviour-change layer.** EAST nudges, Β£-saved value receipt, quick-reply chips (DCMS/COM-B grounded). | |
| - [x] **P6 - Traces.** JSONL logging + in-chat "how I answered" panel. | |
| - [x] **P7 - KB refinement.** Curate all 17 hub resources, filter time-bound junk, tag seasonal pages. | |
| - [x] **P8 - The Hive, page-level.** Reverse the exclusion: crawl all 57 pages | |
| with provenance (`build_hive_kb.py`), `hive_info` tool, Hive in the graph | |
| (open-late, archives, 26 capabilities), council-wins-on-conflict rule. | |
| - [x] **P9 - Copy-level "where to get it".** `where_to_get`: per-branch | |
| holdings/status from the item detail page (two parse strategies, fail-soft), | |
| free-reservation steps, BorrowBox deep links from the Atom feed's | |
| Electronic Access field. *Live-verify with `python library_sources.py`.* | |
| - [ ] **P10 - Deploy** to the Space + `HF_TOKEN` + smoke-test (user action), | |
| incl. the new self-test Β§5 (copy-level) against the live catalogue. | |
| - [ ] **P11 - Stretch:** custom `gr.Server` frontend; a small fine-tune (badge); llama.cpp local run (). | |
| ## The behaviour-change layer (why, not just what) | |
| Grounded in [DCMS *What works to engage non-users*](https://www.gov.uk/government/publications/what-works-to-engage-library-non-users) (COM-B) + the | |
| Behavioural Insights Team **EAST** framework: | |
| - **Easy** β quick-reply chips, exact "what you need", deep links. | |
| - **Attractive** β Β£-saved "value receipt" (DCMS's strongest reframe: money-saving). | |
| - **Social/Timely** β one contextual "did you know?" nudge at the moment of contact. | |
| - **Awareness of breadth** (the #1 barrier) β the nudge engine surfaces hidden gems. | |
| - **Measurement loop** β trace logs which nudges convert β evidence for Jack's campaigns. | |
| ## Trace & eval strategy (Open Trace) | |
| Every turn writes one JSON object to `traces.jsonl` (route β steps β answer β sources β | |
| timing), close to the hackathon's own trace-dataset schema. `trace.push_to_hub(repo_id)` | |
| uploads it as a dataset. The same trace renders in-chat as a "how I answered" panel | |
| (Best Agent evidence). Future: a golden-question eval set scoring route accuracy + | |
| source correctness. | |
| ## Badge roadmap | |
| Best Agent Β· Open Trace Β· Field Notes Β· Off-Brand β (server.py) Β· | |
| Off-the-Grid / Llama Champion β (local llama.cpp) Β· Well-Tuned (next). | |
| ## Risks & mitigations | |
| | Risk | Mitigation | | |
| |---|---| | |
| | HF Inference flaky / no token | **No-LLM fallback** renders raw live data - demo never breaks | | |
| | Council site HTML changes | Re-run `build_kb.py` (re-crawl) any time; tools fail soft | | |
| | SirsiDynix slow/timeouts | per-call try/except; app degrades gracefully | | |
| | Hive site goes stale again | every Hive fact shows its crawl date; council wins on conflict; `build_hive_kb.py` re-crawls in minutes | | |
| | Detail-page holdings markup shifts | two independent parse strategies (table + branch-name text scan); if both miss, the answer says so and links the item page - never guesses | | |
| | Gradio 6 needs Py3.10+ | tested logic locally; boot-test on the Space first | | |
| | Facility data sparse (e.g. "study space") | multi-hop honest about coverage; lead demo on cafΓ©+meeting | | |
| ## Future work | |
| Fine-tune a tiny model on Qβtool routing; live PressReader title search; FOI ingestion | |
| (WhatDoTheyKnow) as a transparency feature; auto-generated "Shelf Life" podcast + | |
| share-cards (see [IDEAS.md](IDEAS.md)); per-branch service mapping. | |