# Pricing & Profitability Analyst — AI Agent (Pilot) The first buildable agent from the [Amazon 1000+ product launch team](../agents_plans/). It automates the Pricing Analyst's gate: for each SKU it builds the full fee stack, computes **contribution margin / break-even / MAP**, checks **competitive price + Buy Box / suppression**, then **proposes** a price and an `APPROVED` / `BLOCKED` / `NEEDS_REVIEW` decision. A human approves before anything is written back to the master tracker. Built on **LangGraph** (stateful, gated, auditable) + **OpenAI** (narrative only — never arithmetic). All money math lives in a pure, unit-tested module. ## Architecture ``` enrich ─▶ compute_margin ─▶ fetch_competitive ─▶ evaluate ─▶ human_review (interrupt) ─▶ write_back │ provider │ │ margin_engine │ │ provider │ │ gate │ │ HITL │ │ tracker │ ``` - **`providers.py`** — market-data seam: `cosmos` (live) ↔ `mock` (offline). Nodes are backend-agnostic. - **`cosmos/`** — real COSMOS integration: `client.py` (auth + token refresh + retries), `service.py` (products, take-home fee quote, **invp sales-trend + inventory**, **bulk calculator**, price read, guarded price-write stub), `models.py` (typed responses). - **`analyze.py`** — the price verdict: combines per-unit margin (`takehome-calculator`), the **6-month sales trend** (`invp-insight`: `averageSale6Months` vs 7/30-day), and **total economics** (`bulk-calculator`: volume − storage on current inventory) → GOOD / CAUTION / POOR. - **`tools/margin_engine.py`** — pure formulas. `stack_from_quote()` builds the fee stack from COSMOS's real dollar fees; `worst_case_stack()` is the synthetic mock path. Golden values (mock): break-even **$16.76**, MAP **$19.00**, CM **~28%**. - **`tools/gate.py`** — deterministic APPROVED/BLOCKED/NEEDS_REVIEW (playbook §13). - **`tools/tracker.py`** — SKU list in / decisions out: `csv` ↔ `gsheets`. - **`llm.py`** — OpenAI structured output; falls back to a template if no key. - **`graph.py`** — LangGraph wiring + `interrupt()` for human approval. Competitive price / Buy Box / suppression comes from **Apify** (`junglee/Amazon-crawler`) when `APIFY_TOKEN` is set: SKU → COSMOS ASIN → scrape `amazon.com/dp/{ASIN}`. Without the token the competitive gate stays `UNKNOWN` (COSMOS has no Buy Box data). For a covered product line the **comparison workbook** takes precedence over the per-ASIN scrape — see *Coverage* in [ARCHITECTURE.md](ARCHITECTURE.md), which also documents which of the two scrapers is authoritative for Buy Box state and why. ## Setup ```bash pip install -e ".[dev]" cp .env.example .env # then fill COSMOS_EMAIL / COSMOS_PASSWORD # Optional Buy Box: set APIFY_TOKEN (and APIFY_SELLER_ID for WON vs LOST_PRICE) ``` `.env` (git-ignored) holds secrets. Defaults: `DATA_BACKEND=cosmos`, `TRACKER_BACKEND=csv`. Set `DATA_BACKEND=mock` to run fully offline (tests + local dev, no credentials). ## Dashboard UI ```bash pip install -r requirements.txt # streamlit + plotly + pandas + numpy streamlit run app.py ``` One-page pricing dashboard in the Utopia/CRAI design system (cream paper, teal primary, coral accent, navy chrome): stat tiles, action pills (↑ Raise / ↓ Lower / → Hold / 🔍 Check), and a recommendation queue where each SKU expands into Approve / Modify / Reject plus seven analysis tabs — price & demand, inventory outlook, scenarios, competitors, PPC, costs, and AI reasoning. Two ways to analyze (sidebar): - **Single product** — enter one SKU for a full price analysis. - **Product line** — enter a SKU prefix and a product-count slider to analyze a whole line at once. Live COSMOS data only: every number comes from the real pipeline (take-home fees, 6-month history, elasticity, actual profit, optional competitor Buy Box prices). The previous analyst UI is still available: `streamlit run legacy_app.py`. ## Run (CLI) ```bash # ANALYZE a price — full breakdown + 6-month trend + AI narrative + suggested price: python -m pricing_agent.cli --sku --price 24.99 --analyze # BULK — scan a product line, ranked worst-first with suggested prices: python -m pricing_agent.cli --bulk --sku-prefix UBMICRO --limit 15 # Live COSMOS, one real SKU at a candidate price (interactive approval): python -m pricing_agent.cli --sku --price 24.99 # Non-interactive (approve healthy, reject the rest): python -m pricing_agent.cli --sku --price 24.99 --auto smart # Offline demo on the sample tracker: python -m pricing_agent.cli --all --backend mock --auto smart # Live COSMOS read-only health check: python scripts/cosmos_smoke.py 24.99 ``` Outputs: `data/sample_skus_out.csv` (pricing columns + status) and `data/audit_log.csv`. ## Test ```bash pytest # margin engine, gate, COSMOS mapping, end-to-end graph (all offline) ``` ## Going live | Switch | What you need | |---|---| | `DATA_BACKEND=cosmos` | `COSMOS_EMAIL` / `COSMOS_PASSWORD` in `.env` (already wired) | | Price write-back to COSMOS | Confirm the `price_adjustment.edit_price` POST/PUT endpoint, then fill `CosmosPricingService.submit_price_approval()` | | `TRACKER_BACKEND=gsheets` | Google service-account JSON + `TRACKER_SHEET_ID` | | Live LLM rationale | `OPENAI_API_KEY` in `.env` | | Buy Box / competitor gate | `APIFY_TOKEN` in `.env` (scrapes ASIN PDP via `junglee/Amazon-crawler`) | | Confirm Buy Box owner | Set `APIFY_SELLER_ID` to your Amazon merchant id | Every configurable value lives in [.env.example](.env.example) (credentials, tokens, paths) or [config/pricing_rules.yaml](config/pricing_rules.yaml) (thresholds and policy). The COSMOS endpoints themselves are catalogued in `COSMOS_API.postman_collection.json`.