personal-shopperPersonal Shopper — multi-agent product/service research and recommendation for Saudi Arabia. USE WHEN: - User asks to find, compare, recommend, or buy a prod...
Install via ClawdBot CLI:
clawdbot install Abdullah4AI/personal-shopperAn agent orchestration skill. The main assistant acts as Router/Orchestrator, spawning sub-agents to research products or services, then scoring and rendering a final Arabic HTML report.
Reference files in references/ provide supplementary detail. If any reference file contradicts this file, follow SKILL.md.
[User Request]
|
[Router] ← main assistant, NOT a sub-agent
|
┌────┼──────────┐
│ │ │
Simple Standard Service
Scout A+K Finder
│ (parallel) │
│ │ │
│ Bargain Verifier
│ (sequential) │
└────┼──────────┘
|
[Court]
|
[Renderer → HTML Report]
The main assistant classifies every request. Do not spawn a sub-agent for routing.
{
"category": "electronics|grocery|medicine|clothing|furniture|services|automotive|toys",
"type": "product|service",
"complexity": "simple|standard|service",
"search_language": "both|ar_only",
"stores_tier1": ["..."],
"stores_tier2": ["..."],
"mainstream_brands": ["brand1", "brand2"],
"query_en": "English search query",
"query_ar": "استعلام بحث عربي"
}
| Path | Trigger | Agents | Token Budget |
|------|---------|--------|-------------|
| Simple | ANY 2 of: commodity item, est. price < 50 SAR, exact product specified, fungible | Scout → Court → Renderer | ~115K |
| Standard | Meaningful product differentiation (electronics, furniture, clothing, appliances) | Advocate + Skeptic ‖ → Bargain Hunter → Court → Renderer | ~235K |
| Service | Services (massage, salon, restaurant, repair, delivery) | Finder → Verifier → Court → Renderer | ~155K |
| Category | Language |
|----------|----------|
| Electronics, Clothing, Furniture | both (EN + AR queries) |
| Grocery, Medicine, Services | ar_only |
Router identifies the top 2-3 dominant brands in the category and passes them as mainstream_brands. These are banned for the Skeptic agent. Examples:
| Category | Stores |
|----------|--------|
| Electronics | amazon.sa, noon.com, jarir.com, extra.com |
| Grocery | nana.sa, danube.com.sa, carrefourksa.com |
| Medicine | nahdi.sa, al-dawaa.com |
| Clothing | namshi.com, noon.com, 6thstreet.com |
| Furniture | ikea.sa, homebox.sa, noon.com, homezmart.com |
| Services | Google Maps, fresha.com |
| General | noon.com, amazon.sa |
| Category | Stores |
|----------|--------|
| Electronics | aliexpress.com, ubuy.com.sa |
| Furniture | pan-home.com, abyat.com |
| General | haraj.com.sa, Facebook Marketplace |
| Store | Method | Notes |
|-------|--------|-------|
| amazon.sa | web_fetch ✅ | |
| noon.com | web_fetch ✅ | |
| jarir.com | camofox ⚠️ | JS-heavy |
| extra.com | web_fetch ✅ | |
| nana.sa | camofox ⚠️ | JS-heavy |
| danube.com.sa | camofox ⚠️ | JS-heavy |
| Google Maps | camofox ⚠️ | Or Google Local Pack via DDG |
| All others | web_fetch first, camofox fallback | |
This is the most critical section. Token overflow is the #1 cause of agent failure.
web_fetch
web_fetch("https://lite.duckduckgo.com/lite/?q=YOUR+QUERY+HERE")
Returns ~5K tokens (titles + URLs + snippets). Then web_fetch on promising result URLs for details (~10K tokens each).
web_search (Brave API, if available)1. DDG Lite search (query_ar) → scan results → pick 3-5 URLs
2. DDG Lite search (query_en) → scan results → pick 3-5 URLs [if language=both]
3. web_fetch each promising URL → extract product name, price, specs
4. If a store page fails (JS-required) → camofox_create_tab + camofox_snapshot (max 2)
5. If web_search is available → use it for supplementary queries
Each agent is spawned as a sub-agent with a specific task prompt, input data, and output schema.
When: Simple path selected by Router.
Task prompt:
Find the top 3 options for a commodity product in Saudi Arabia (Riyadh). Focus on availability and price. Use DuckDuckGo Lite as primary search.
Input from Router:
{
"query_ar": "...",
"query_en": "...",
"search_language": "ar_only|both",
"stores_tier1": ["..."],
"category": "..."
}
Instructions:
query_ar (and query_en if search_language=both)web_fetch calls totalcamofox snapshot (only if critical store is JS-blocked)camofox_screenshot and save to shopping-reports/screenshots/{date}-{slug}.png. Include path in output.Output schema:
{
"candidates": [
{
"name": "Product Name",
"brand": "Brand",
"price_sar": 29.99,
"store": "noon.com",
"source_url": "https://...",
"price_from_page": true,
"screenshot_path": "shopping-reports/screenshots/2026-02-19-product-name.png",
"notes": "Free delivery, in stock"
}
],
"search_summary": "Searched 3 stores, found 5 listings, selected top 3 by price"
}
Token budget: 60K
When: Standard path. Runs in parallel with Skeptic.
Task prompt:
Find the BEST product in this category regardless of price. Prioritize quality, build, real user reviews, and long-term value. The goal is the best possible product for the user.
Input from Router:
{
"query_ar": "...",
"query_en": "...",
"search_language": "both",
"stores_tier1": ["..."],
"category": "..."
}
Instructions:
web_fetch calls, max 2 camofox snapshotscamofox_screenshot immediately and save to shopping-reports/screenshots/{date}-{brand-model-slug}.png. Create the folder if it doesn't exist. Include path in output.Output schema:
{
"candidates": [
{
"name": "Product Name",
"brand": "Brand",
"price_sar": 599,
"store": "amazon.sa",
"source_url": "https://...",
"price_from_page": true,
"screenshot_path": "shopping-reports/screenshots/2026-02-19-brand-model.png",
"quality_evidence": "4.6★ on 2,300 reviews, recommended by rtings.com",
"why_best": "Highest color accuracy in price range, 3-year warranty"
}
],
"search_summary": "..."
}
Token budget: 60K
When: Standard path. Runs in parallel with Advocate.
Task prompt:
Find alternatives the mainstream ignores. BANNED from recommending these brands: {mainstream_brands}. Find genuinely different products — not variations of popular ones. Check Tier 2 stores. Look for underdog brands with real quality.
Input from Router:
{
"query_ar": "...",
"query_en": "...",
"search_language": "both",
"stores_tier1": ["..."],
"stores_tier2": ["..."],
"mainstream_brands": ["Samsung", "LG"],
"category": "..."
}
Instructions:
mainstream_brandsweb_fetch calls, max 2 camofox snapshotscamofox_screenshot immediately and save to shopping-reports/screenshots/{date}-{brand-model-slug}.png. Include path in output.Output schema: Same as Advocate, plus:
{
"candidates": [
{
"name": "...",
"brand": "...",
"screenshot_path": "shopping-reports/screenshots/2026-02-19-brand-model.png",
"why_different": "Chinese brand with 90% of Samsung quality at 60% price, popular on r/monitors"
}
]
}
Token budget: 60K
When: Standard path. Runs AFTER Advocate and Skeptic complete.
Task prompt:
Given a list of products already researched, find the best LOCAL price for each, check for coupons/cashback/installments, and advise on timing. Do NOT search for new products.
Input: Combined candidate list from Advocate + Skeptic (deduplicated).
Instructions:
web_fetch calls (hard cap — plan carefully)camofox unless absolutely necessary (max 1)Output schema:
{
"price_checks": [
{
"candidate_name": "...",
"best_price_sar": 499,
"best_store": "noon.com",
"source_url": "https://...",
"price_from_page": true,
"coupon": "SAVE50 on almowafir.com (-50 SAR)",
"cashback": "Al Rajhi 5% on noon.com",
"installments": "Tamara 4x125 SAR",
"effective_price_sar": 424
}
],
"timing": {
"recommendation": "buy_now|wait|unclear",
"reason": "Ramadan sale expected in 3 weeks, historically 20-30% off electronics on noon",
"wait_until": "2026-03-10"
}
}
Token budget: 60K
When: Service path selected.
Task prompt:
Locate and rank local services in Riyadh, Saudi Arabia. Use Google Local Pack results via DuckDuckGo. Focus on: rating, review count, price range, location.
Input from Router:
{
"query_ar": "مساج رياض",
"category": "services",
"stores_tier1": ["Google Maps", "fresha.com"]
}
Instructions:
{query_ar} الرياض and {query_ar} site:fresha.comweb_fetch on top results for prices and detailsweb_fetch calls, max 2 camofox snapshotsOutput schema:
{
"candidates": [
{
"name": "Spa Name",
"rating": 4.7,
"review_count": 342,
"price_range": "200-400 SAR",
"address": "حي العليا، الرياض",
"source_url": "https://...",
"hours": "10AM-12AM",
"notes": "Highly rated for deep tissue"
}
]
}
Token budget: 60K
When: Service path. Runs after Finder.
Task prompt:
Given the Finder's top 2 service picks, verify they are real, open, and accurately described. Check reviews for authenticity, confirm prices, confirm operating hours.
Input: Finder's top 2 candidates.
Instructions:
web_fetch each candidate's source URL — confirm it loads, info matches"{service name}" review الرياض)web_fetch callsOutput schema:
{
"verifications": [
{
"candidate_name": "...",
"verified": true,
"price_confirmed": true,
"still_open": true,
"review_authenticity": "high|medium|low",
"red_flags": [],
"notes": "Reviews look genuine, mix of 3-5 stars, specific details mentioned"
}
]
}
Token budget: 40K
When: All paths, after research agents complete.
Task prompt:
Score all candidates using the weighted scoring framework. Do NO searching. Only judge based on data provided. Be strict. Apply all rules.
Input: All candidate data + Bargain Hunter/Verifier data (if applicable) + scoring weights for category.
Instructions:
web_fetch one source_url, confirm product/service existsCourt Rules:
source_url → score capped at 30 (effectively eliminated)price_from_page: false → Source Trust capped at 60; if estimated → capped at 40Output schema:
{
"rankings": [
{
"rank": 1,
"name": "...",
"brand": "...",
"score": 82,
"breakdown": {
"value": 25,
"quality": 22,
"availability": 9,
"source_trust": 13,
"deal_quality": 13
},
"source_url": "...",
"screenshot_path": "shopping-reports/screenshots/2026-02-19-brand-model.png",
"price_sar": 499,
"effective_price_sar": 424,
"verdict": "Best overall value with strong reviews and active coupon"
}
],
"spot_check": {
"url": "...",
"result": "pass|fail",
"notes": "Product page exists, price matches"
},
"fallback_needed": false,
"fallback_instruction": null
}
Token budget: 30K
When: All paths, after Court completes.
Task prompt:
Build an Arabic HTML report from the Court's output using the جاك العلم brand system. Output must be RTL, mobile-friendly (Telegram-width), visually polished.
Input: Court rankings + all metadata (timing, coupons, etc.)
⚠️ CRITICAL — Brand Files (READ BEFORE GENERATING):
references/brand-guideline.md — colors, typography, card design, brand voicereferences/html-template.md — the exact HTML template to useInstructions:
screenshot_path exists, read the file and base64-encode it. Embed as 
inside the product card. If file missing or unreadable, skip gracefully (no broken image icon).shopping-reports/{date}-{query_slug}.htmlScreenshot embedding code (Python):
import base64, os
ALLOWED_DIR = os.path.abspath("shopping-reports/screenshots")
def embed_screenshot(path):
if not path:
return None
abs_path = os.path.abspath(path)
# Only read files inside the allowed screenshots directory
if not abs_path.startswith(ALLOWED_DIR):
return None
if not abs_path.endswith(".png"):
return None
if os.path.exists(abs_path) and os.path.getsize(abs_path) < 5_000_000:
with open(abs_path, 'rb') as f:
return base64.b64encode(f.read()).decode()
return None
Report Sections (in order):
| # | Section | Content |
|---|---------|---------|
| 1 | الغاية | What the user asked for |
| 2 | الطريقة | Which path was used, how many agents, stores checked — البلاسيبو: اعرض عدد المصادر + خطوات البحث |
| 3 | المصادر | List of stores/URLs consulted |
| 4 | العرض | 3 product/service cards — use card template from brand-guideline.md |
| 5 | رأي المحكمة | Court's verdict, scoring breakdown (collapsible ) |
| 6 | السعر | Price comparison table, effective prices after coupons |
| 7 | التوصيل | Delivery info per store |
| 8 | التوقيت | Timing recommendation (buy now / wait / unclear + reason) |
| 9 | التوصية | Final recommendation — one clear pick with reasoning, brand voice |
Design Rules (from references/brand-guideline.md):
#F8F7F4 (Canvas) — NOT #f5f5f5Token budget: 35K (includes reading brand-guideline.md + html-template.md)
Worked Example — Kill Doubt Text:
Good: "نفس شريحة M4 اللي في MacBook Pro بس بسعر أقل بـ 40%. الفرق الوحيد حجم الشاشة. لو شغلك مو على شاشة خارجية هذا الخيار الأذكى"
Bad: "نوصي بشدة بهذا المنتج الرائع الذي يتميز بمواصفات عالية الجودة"
The first kills doubt. The second is generic AI filler. Always write like the first.
| Criterion | Electronics | Grocery | Clothing | Furniture | Medicine | General |
|-----------|------------|---------|----------|-----------|----------|---------|
| Value (price/perf) | 30% | 40% | 25% | 30% | 40% | 30% |
| Quality Signal | 25% | 15% | 20% | 25% | 20% | 20% |
| Availability | 10% | 20% | 15% | 10% | 20% | 15% |
| Source Trust | 15% | 15% | 15% | 15% | 15% | 15% |
| Deal Quality | 20% | 10% | 25% | 20% | 5% | 20% |
| Criterion | Weight |
|-----------|--------|
| Rating | 30% |
| Review Volume | 15% |
| Price | 25% |
| Location (Riyadh proximity) | 15% |
| Verification | 15% |
Value (price/performance): How much you get per SAR. Cheapest ≠ best value — a 500 SAR item lasting 5 years beats a 200 SAR item lasting 1 year.
Quality Signal: Review scores (weighted by count), expert reviews, build materials, warranty length. Community evidence (Reddit, forums) > marketing specs.
Availability: In stock? Local delivery? Same-day/next-day? International-only → capped at 30.
Source Trust: Known store? Price verified on page? Secure checkout? source_url required or score capped at 30. price_from_page: false → capped at 40.
Deal Quality: Active coupons, cashback, installment options, bundle deals. Higher = more savings available right now.
When a store is unreachable or returns no results:
1. web_fetch fails → retry once with different URL pattern
2. Still fails → try camofox (if within budget)
3. camofox fails → mark store as "غير متاح" and move to next store
4. If ALL Tier 1 stores fail → switch to Tier 2 stores
5. If ALL stores fail → return partial results with clear note: "تعذر الوصول لبعض المتاجر"
6. Never hallucinate prices or availability from failed fetches
Court returns fallback_needed: true
→ Router reads fallback_instruction
→ Max 1 retry
→ Retry MUST change something:
- Different query terms
- Different stores (add Tier 2)
- Different language (try EN if was AR-only)
→ Re-run the same path with changes
→ If still < 2 results after retry:
- Generate "limited results" report
- Include manual search suggestions
- Be honest: "لم نجد خيارات كافية"
Every candidate in every path must include:
| Field | Required | Effect if Missing |
|-------|----------|-------------------|
| source_url | Yes | Score capped at 30 |
| price_from_page | Yes | If false → Source Trust capped at 40 |
| store | Yes | Used for delivery/trust assessment |
Court spot-check: The Court web_fetches 1 random source_url per run to confirm the product/service exists and price is approximately correct.
1. User: "أبي شاشة كمبيوتر 27 بوصة للتصميم"
2. Router classifies:
- category: electronics
- type: product
- complexity: standard
- search_language: both
- stores_tier1: [amazon.sa, noon.com, jarir.com, extra.com]
- stores_tier2: [aliexpress.com, ubuy.com.sa]
- mainstream_brands: [Samsung, LG]
- query_en: "27 inch monitor for design color accurate"
- query_ar: "شاشة 27 بوصة للتصميم دقة ألوان"
3. Router spawns Advocate + Skeptic IN PARALLEL:
- Advocate gets: query, language=both, tier1 stores
- Skeptic gets: query, language=both, tier1+tier2 stores, banned=[Samsung, LG]
4. Both complete → Router collects results → deduplicates
5. Router spawns Bargain Hunter SEQUENTIALLY:
- Input: deduplicated candidate list from step 4
- Checks prices, coupons, timing
6. Bargain Hunter completes → Router spawns Court:
- Input: all candidates + bargain data + scoring weights for electronics
7. Court scores, ranks, spot-checks → output top 3
8. Router spawns Renderer:
- Input: Court output + all metadata
- Generates HTML report → saves to shopping-reports/
9. Router sends report to user
1. User: "أبي بطاريات AA"
2. Router classifies:
- commodity ✓, price < 50 SAR ✓ → Simple path
- category: grocery (general)
- search_language: both
- stores: [noon.com, amazon.sa, nana.sa]
3. Router spawns Scout only → finds 3 options
4. Router spawns Court → scores
5. Router spawns Renderer → HTML report
1. User: "أبي مساج في الرياض"
2. Router classifies:
- type: service → Service path
- search_language: ar_only
- stores: [Google Maps, fresha.com]
3. Router spawns Finder → finds 5 services
4. Router spawns Verifier → verifies top 2
5. Router spawns Court → scores (service weights)
6. Router spawns Renderer → HTML report
Use the platform's sub-agent mechanism. Each agent gets:
shopping-{agent_name} (e.g., shopping-advocate)web_fetch, web_search, camofox_* (with limits stated per agent)Advocate and Skeptic can run simultaneously. Spawn both, wait for both to complete before spawning Bargain Hunter.
Simple: Scout → Court → Renderer
Standard: [Advocate ‖ Skeptic] → Bargain Hunter → Court → Renderer
Service: Finder → Verifier → Court → Renderer
Standard path runs 5+ sequential agent steps and can exceed 200K tokens. Design for continuity:
previous_response_id when continuing multi-step orchestration in the same thread.null and continue with available data.shopping-reports/ directory.shopping-reports/{date}-{query_slug}.htmlshopping-reports/screenshots/{date}-{brand-model}.pngshopping-reports/ directory (reports and screenshots)references/ within this skill, and shopping-reports/screenshots/*.png for base64 embeddingThese are hard-won. Violating any of these will produce bad results.
| Don't | Why | Do Instead |
|-------|-----|------------|
| Don't tell Skeptic to "look for alternatives" | Produces the same mainstream products with different wording | Ban specific brands: mainstream_brands: ["Samsung", "LG"] |
| Don't use Camoufox for search result pages | 50K tokens per snapshot, overflows context | Use DDG Lite (~5K tokens) for search. Camofox only for specific product pages |
| Don't pass raw HTML to Court | Court crashes or hallucinates from unstructured data | Always pass structured JSON summaries from research agents |
| Don't spawn Bargain Hunter before researchers finish | Missing candidate data causes empty price checks | Enforce sequential: Advocate+Skeptic complete → then Bargain Hunter |
| Don't add mainstream_brands after Skeptic starts searching | Bans are ineffective retroactively | Router must pass brands in the initial spawn payload |
| Don't assume web_search is available | Brave API key may be missing | DDG Lite is the guaranteed fallback. Always try it first |
| Don't skip timing advice | Users overpay by 30-40% buying before sales | Bargain Hunter always checks: Ramadan, White Friday, 11.11, back-to-school |
| Don't trust marketing specs over community reviews | Specs lie. Real users don't | Agents prioritize Reddit, forums, real-user reviews over product page claims |
| Don't use Standard path for batteries or USB cables | Wastes ~120K tokens on commodity items | Use Simple path when ANY 2 of: commodity, <50 SAR, exact product specified, fungible |
| Don't use Advocate+Skeptic for services | Services need location, ratings, hours — not specs and builds | Use Finder+Verifier path for services |
| Don't skip screenshots when using Camofox | Screenshots are free (0 tokens) and make reports trustworthy | Always camofox_screenshot right after opening a product page |
| Component | Simple | Standard | Service |
|-----------|--------|----------|---------|
| Router | 5K | 5K | 5K |
| Scout | 60K | — | — |
| Advocate | — | 60K | — |
| Skeptic | — | 60K | — |
| Bargain Hunter | — | 60K | — |
| Finder | — | — | 60K |
| Verifier | — | — | 40K |
| Court | 30K | 30K | 30K |
| Renderer | 35K | 35K | 35K |
| Total | ~130K | ~250K | ~170K |
Generated Mar 1, 2026
A user in Saudi Arabia wants to buy a new laptop for work and entertainment, with a budget of around 3000 SAR. The skill will research options from Amazon.sa, Noon.com, and Jarir.com, comparing specs like RAM, storage, and processor, then provide a ranked list with prices and coupons.
A user asks to compare sofas from IKEA and Homebox for a living room, focusing on durability and price under 2000 SAR. The skill will fetch product details, check availability in Riyadh, and include installment options via Tabby or Tamara in the report.
A user needs to find the best deals on specific grocery items like coffee or snacks from Nana.sa and Danube.com.sa. The skill will search in Arabic only, verify current prices, and highlight any available cashback offers through bank apps.
A user requests recommendations for a massage or salon service in Riyadh. The skill will use Google Maps or Fresha.com to find highly-rated providers, check reviews and pricing, and output a mobile-friendly HTML report in Arabic.
A user wants to buy car accessories like seat covers or phone holders, comparing options on Noon.com and Haraj.com.sa. The skill will research products, ensure they fit the user's vehicle model, and include verified seller ratings in the recommendation.
Partner with e-commerce platforms like Amazon.sa or Noon.com to earn commissions on sales generated through links in the HTML reports. Integrate tracking codes and promote exclusive deals to increase conversion rates and revenue.
Offer premium tiers where users pay a monthly fee for unlimited product research requests, priority support, and access to exclusive coupons or cashback offers. Target busy professionals or expats in Saudi Arabia who value time savings.
License the skill to businesses such as banks or telecom companies in Saudi Arabia, integrating it into their apps to provide shopping assistance as a value-added service. Customize reports with branded elements and specific product categories.
💬 Integration Tip
Ensure proper configuration of web_fetch and camofox tools with allowlist-only network security to handle JS-heavy sites like Jarir.com efficiently.
Captures learnings, errors, and corrections to enable continuous improvement. Use when: (1) A command or operation fails unexpectedly, (2) User corrects Clau...
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
Search and analyze your own session logs (older/parent conversations) using jq.
Typed knowledge graph for structured agent memory and composable skills. Use when creating/querying entities (Person, Project, Task, Event, Document), linking related objects, enforcing constraints, planning multi-step actions as graph transformations, or when skills need to share state. Trigger on "remember", "what do I know about", "link X to Y", "show dependencies", entity CRUD, or cross-skill data access.
Ultimate AI agent memory system for Cursor, Claude, ChatGPT & Copilot. WAL protocol + vector search + git-notes + cloud backup. Never lose context again. Vibe-coding ready.
Headless browser automation CLI optimized for AI agents with accessibility tree snapshots and ref-based element selection