shopstack / README.md
pranaysuyash's picture
Sync ShopStack HEAD f5f6237
e6dc493 verified
|
Raw
History Blame Contribute Delete
14.7 kB

A newer version of the Gradio SDK is available: 6.20.0

Upgrade
metadata
title: ShopStack
emoji: πŸ›’
colorFrom: green
colorTo: blue
sdk: gradio
sdk_version: 6.17.3
app_file: app.py
pinned: false
tags:
  - shopstack
  - gradio
  - inventory
  - shopping
  - offline-first
  - household

ShopStack

Doc links: Several links in this README point to Docs/ paths that are intentionally local-only (see Docs/README.md). They work in a local workspace but 404 from a clean clone. For canonical architecture, see shopstack/module_registry.py and the code under shopstack/. Git-tracked docs (MODEL_CATALOG.md, this README) are reachable from any clone.

Local-first, off-the-grid shopping intelligence platform. Know what you have, what to use soon, what to buy, what to skip, and where to buy from β€” without sending your data to the cloud.

ShopStack is a stack of shopping intelligence layers: home inventory (ShopStock), shopping lists and market baskets (ShopBasket), retailer price comparison (ShopCompare), scanning and import (ShopLens), price history and preferences (ShopMemory), and a reasoning agent (ShopAgent) that decides buy/skip/use-soon across all modules.

Philosophy

ShopStack runs entirely locally β€” SQLite database (WAL mode), mockable provider interfaces, and a Gradio workflow UI that works offline. The "Off the Grid" path means zero cloud dependencies for core functionality. The default mock providers let you build and test the full app without loading any ML models.

Total parameter limit: ≀32 billion parameters across all loaded models.

Modules

Module Purpose
ShopStock Inventory, pantry, fridge, expiry, low-stock, use-soon
ShopBasket Shopping list, cart builder, market basket optimization
ShopCompare Retailer price comparison (Swiggy, Blinkit, Zepto, ...)
ShopLens Scanning: barcode, photo, receipt, barcode
ShopMemory Price history, household preferences, field notes
ShopAgent Reasoning: buy/skip/use-soon/compare decisions
Sources Retailer datasets (Swiggy Instamart + future)

See Docs/SHOPSTACK_PRODUCT_ARCHITECTURE.md for full details.

Gradio Workflows

ShopStack is organized around workflow experiences:

  • Today β€” Decision-first dashboard: what to buy, skip, use soon, and compare
  • Ask ShopStack β€” Natural language queries across all modules
  • Shopping List β€” Create, classify (buy/skip/use-soon), and complete shopping plans
  • Market Lens β€” Scan items via camera or voice, compare to inventory
  • Add Purchase β€” Record what was bought (price, store, location)
  • Find Item at Home β€” Search inventory by location and status
  • Use Soon β€” Expiring and aging items flagged for attention
  • Price Memory Check β€” Price history, trends, and best-store intelligence
  • Traces β€” Workflow audit trail with redacted export
  • Field Notes β€” Household notes and preferences

Quick Start

uv venv --python 3.13
uv pip install -e ".[dev]"
uv run python app.py

Open http://localhost:7860 in your browser.

Market Snapshot Import

ShopStack can ingest the real Swiggy Instamart fresh vegetables snapshot found in data/swiggy_fresh_vegetables_cards_6jun26.json (or the matching CSV) into the local price observation database.

uv run python scripts/import_swiggy_snapshot.py

Imported observations are tagged with source_event_id = swiggy_fresh_vegetables_20260606 so they can be filtered or audited later.

Tests

uv run pytest tests/ -v
uv run pytest benchmarks/ -v -m benchmark

Run uv run pytest tests/ --collect-only -q for the current test count.

Current Verified by Code Inspection

As of the current code inspection, the following metrics are verified:

  • 26 Database Tables, 2 Views, 2 Triggers, 9 Indexes: app_config, condition_events, correction_events, find_feedback, household_locations, household_members, household_objects, households, inventory_events, inventory_lots, market_record_components, market_records, market_snapshots, movement_events, negative_memory, object_notes, object_sightings, person_associations, preference_signals, price_observations, purchase_events, reconciliation_events, shopping_list_items, shopping_lists, stores, traces (Tables), price_history, agent_traces (Views).
  • 12 Tools: Including semantic_find_item.

Note: For the canonical current-state metrics, run python3 scripts/repo_truth.py. The README is updated when new tables/tabs/tools are added; do not hand-maintain these numbers.

Engineering Mandate: Do not narrow scope to hackathon/MVP. ShopStack is designed as a long-term, bold, and comprehensive intelligence platform. Follow motto_v3.md principles exactly.

Project Structure

shopstack/
  __init__.py
  _version.py               # v0.1.0
  config.py                 # Settings (pydantic-settings, env prefix SHOPSTACK_)
  model_registry.py         # 16 candidate model entries (all ≀32B total)
  schemas/
    models.py               # All Pydantic domain models (14+ classes, 16 enums)
  providers/
    interfaces.py           # 11 abstract provider ABCs
    mock_providers.py       # Full mock implementations for all 11 (Indian/Hinglish data)
    registry.py             # ProviderRegistry factory wired to Settings
  persistence/
    database.py             # SQLite Database (WAL, 26 tables, 2 views, 2 triggers, 9 indexes, full CRUD)
  services/                 # Business logic services (decision engine, shopping, dashboard, preferences, freshness)
  tools/
    registry.py             # ToolRegistry β€” 12 tools executing against Database
  traces/
    export.py               # Trace creation, JSONL export, PII redaction
  data_sources/             # Data source adapters for market snapshots and external feeds
  ui/                       # (reserved)
  configs/                  # (reserved)

app.py                      # Gradio Blocks UI entry point (workflow-first tabs, custom warm CSS)
tests/                      # pytest test suite (run `pytest tests/ --collect-only -q` for current count)
benchmarks/                 # pytest benchmark suite (9 latency markers)

Architecture

Gradio Blocks (app.py)
  β†’ ToolRegistry (12 tools, validates args, calls Database)
    β†’ Database (SQLite WAL, 26 tables, 2 views, 2 triggers, 9 indexes)
  β†’ ProviderRegistry (wired from Settings)
    β†’ MockProviders (default β€” 11 interfaces, all offline)
    β†’ Market services (market source registry load + snapshot status helpers in `shopstack.services.market_sources`)
  β†’ Settings (pydantic-settings, env-overridable)
  β†’ ModelRegistry (16 candidates, not loaded by default)

11 Provider Interfaces

Interface Mock Behavior
STTProvider Returns predefined Hindi/Hinglish phrases
TTSProvider Writes a note about what would be spoken
VisionProvider Randomly samples from 26 common kitchen items
ObjectDetectionProvider Returns plausible bounding boxes + confidences
GroundingProvider Returns grounded item references
SegmentationProvider Returns placeholder masks
OCRProvider Returns mock extracted text
PlannerProvider Returns structured multi-step plans
ToolCallParserProvider Parses intent β†’ tool call candidates
EmbeddingsProvider Returns random 384-d vectors
ImageEditProvider Returns a dummy edited image path

12 Tools

Tool Purpose
add_inventory_item Add a new item to household inventory
update_inventory_item Update details of an existing inventory item
consume_inventory_item Record consumption (partial or full)
move_inventory_item Move an item to a different storage location
find_item Search for an item across inventory and locations
semantic_find_item Search for an item using exact, prefix, and semantic embedding search with match quality scores
create_or_update_shopping_list Create/update the active shopping list
compare_visible_item_to_inventory Compare detected item against current stock
record_price_observation Record a price observation for an item
get_use_soon_items Get items expiring or aging soon
get_next_buy_suggestions Get suggestions for what to buy next
export_anonymized_trace Export an anonymized agent trace

10 Database Tables

inventory_lots, purchase_events, shopping_lists, shopping_list_items, household_locations, movement_events, price_observations, stores, traces, app_config

Compatibility aliases: price_history and agent_traces are exposed as read/delete-compatible views for older docs, tests, and scripts.

18 hierarchical household locations seeded on every init (safe via COUNT check): Home β†’ Kitchen β†’ Fridge β†’ Fridge Door β†’ ..., Pantry β†’ Shelf β†’ ..., etc.

Trace System

Every tool execution creates an agent trace stored in the database. Traces include perception snapshots, inventory context, decision rationale, proposed tool calls, and human confirmation status. On export, traces are redacted for PII:

  • Phone numbers (10+ digits)
  • Email addresses
  • Aadhar numbers (12-digit pattern)
  • PAN numbers (5 letters + 4 digits + 1 letter)
  • Geo addresses (street patterns)

Explicitly not redacted: generic name fields, canonical item names, location names.

Screens

Tab Purpose
Plan Today's Shopping Dashboard workflow β€” today view, use-soon signals, and shopping recommendations
Shopping List View / create / manage the active shopping list
Market Lens: Should I Buy This? Camera / voice input β†’ detect β†’ compare vs inventory
Add Purchase Manual purchase recording form with store, price, item details
Find an Item at Home Search + map lookup for likely storage location
Use Soon / Waste Saver Expiring and aging items with priority list
Price Memory Check Historical price observations per item
Find Item Location Storage hierarchy and item count view
Model Stack Active model stack + budget status and candidate catalog
Agent Trace Agent session trace viewer with redaction preview
Field Notes Agent reasoning and decision log

Configuration

All settings are pydantic-settings with SHOPSTACK_ env prefix:

Operational resource guards are documented in Docs/RESOURCE_OPTIMIZATION_POLICY.md.

Variable Default Description
SHOPSTACK_DB_PATH data/shopstack.db SQLite database file path
SHOPSTACK_APP_PORT 7860 Gradio server port
SHOPSTACK_OFF_THE_GRID true Use mock providers (no cloud)
SHOPSTACK_LOCAL_AUTO_UNLOAD true Unload local model runtime after each local provider call
SHOPSTACK_LOCAL_WHISPER_AUTO_UNLOAD true Unload local STT model after each transcription
SHOPSTACK_TRACE_MAX_ROWS 2000 Maximum number of trace rows to retain
SHOPSTACK_TRACE_TTL_DAYS 30 Delete traces older than this many days
SHOPSTACK_STT_BACKEND mock STT provider selection
SHOPSTACK_TTS_BACKEND mock TTS provider selection
SHOPSTACK_VISION_BACKEND mock Vision provider selection
SHOPSTACK_OBJECT_DETECTION_BACKEND mock Object detection provider
... per-provider backends default to mock

Model Catalog

See MODEL_CATALOG.md for the full living model catalog β€” including downloaded & tested models, parameter budget tracking, runtime backends (MLX, llama.cpp/GGUF, transformers), HF Pro and Modal Labs credit resources, and experiment logs.

The programmatic registry lives in shopstack/model_registry.py (16+ entries across STT, TTS, Vision, OCR, Embeddings, and Planner categories).

  • Active / loaded models: actually selected at runtime.
  • Candidate models: documented options available for future activation.
  • Budget check: only active/loaded models are counted against the 32B cap (enforced by validate_active_model_budget()).

Active design constraint: Total parameter count across all simultaneously active models must not exceed 32 billion. Mock mode shows an active-loaded stack of 0B.

Key Design Decisions

  • Single shared schemas file β€” models are interconnected and share enums; a single file avoids circular imports.
  • Provider ABCs named *Provider β€” STTProvider, not STT; mock classes named Mock*Provider.
  • PurchaseEvent enriched with per-item fields β€” canonical_name, quantity, unit, total_price live on the event, not on a separate join table.
  • PriceObservation defaults β€” observation_date defaults to date.today().
  • PII redaction is targeted β€” only phone, email, Aadhar, PAN, and address patterns are redacted. Generic name keys are preserved.
  • No auto-purchase or payment scraping β€” design-level constraint. ShopStack tells you what to buy, it doesn't buy for you.

Development

uv pip install -e ".[dev]"
uv run pytest tests/ -v
uv run pytest benchmarks/ -v -m benchmark
uv run python app.py

Deployment

ShopStack can run via Docker or on any of the supported platforms.

Docker (local)

docker compose up --build
# Open http://localhost:7860

Data persists in a Docker volume (shopstack_data).

Docker (standalone)

docker build -t shopstack .
docker run -p 7860:7860 -v shopstack_data:/app/data shopstack

Railway

  1. Push your repo to GitHub.
  2. Create a new project on Railway β†’ Deploy from GitHub repo.
  3. Railway auto-detects Dockerfile and railway.json.
  4. Add a Volume with mount path /app/data (1 GB) for SQLite persistence.
  5. (Optional) Set SHOPSTACK_HF_API_KEY and SHOPSTACK_PLANNER_BACKEND=huggingface for cloud-backed planning.

Render

  1. Push your repo to GitHub.
  2. Create a new Web Service on Render β†’ Deploy from Dockerfile.
  3. Select the Starter plan ($7/mo) β€” required for persistent disk.
  4. Add a Disk mount at /app/data with 1 GB.
  5. render.yaml is auto-detected if you connect via Blueprint.

Fly.io

# Install flyctl first: https://fly.io/docs/hands-on/install-flyctl/
flyctl launch --dockerfile ./Dockerfile
flyctl volumes create shopstack_data --region <your-region> --size 1
flyctl deploy

See fly.toml for configuration reference.

License

MIT