Skip to content

Scheduled price checking with APScheduler integration #486

@kovtcharov

Description

@kovtcharov

Summary

Integrate APScheduler to enable periodic background price checks for all watchlist products. This is the engine that powers the "track prices over time" capability.

Motivation

Price tracking requires periodic data collection. Without scheduling, users must manually run gaia deals each time. With APScheduler, the agent can check prices on a configurable interval (e.g., every 6 hours) and record them in the database — building the price history that enables trend analysis, charts, and drop alerts.

Design

Architecture

                   ┌──────────────────┐
                   │   APScheduler    │
                   │  (BackgroundJob) │
                   └────────┬─────────┘
                            │ every N hours
                            ▼
                   ┌──────────────────┐
                   │  check_prices()  │
                   │  - fetch watchlist│
                   │  - call APIs     │
                   │  - record prices │
                   │  - detect drops  │
                   │  - send alerts   │
                   └──────────────────┘

Implementation

# src/gaia/agents/deals/scheduler.py
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore

class DealScheduler:
    def __init__(self, agent: "DealAgent", interval_hours: float = 6.0):
        self.agent = agent
        self.interval_hours = interval_hours
        jobstores = {
            "default": SQLAlchemyJobStore(url=f"sqlite:///{agent.db_path}")
        }
        self.scheduler = BackgroundScheduler(jobstores=jobstores)

    def start(self):
        """Start the background scheduler."""
        self.scheduler.add_job(
            self._check_all_prices,
            "interval",
            hours=self.interval_hours,
            id="price_check",
            replace_existing=True,
        )
        self.scheduler.start()

    def stop(self):
        self.scheduler.shutdown()

    def _check_all_prices(self):
        """Fetch prices for all watchlist items and store results."""
        watchlist = self.agent.get_watchlist()
        for item in watchlist:
            try:
                price = self.agent.fetch_current_price(item["product_id"])
                self.agent.record_price(item["product_id"], price)
                self.agent.check_alert_threshold(item, price)
            except Exception as e:
                logger.warning(f"Price check failed for {item['name']}: {e}")

CLI Integration

gaia deals watch                    # Start background monitoring (default 6h)
gaia deals watch --interval 2h      # Custom interval
gaia deals watch --stop             # Stop monitoring
gaia deals watch --status           # Show scheduler status

New Dependency

# pyproject.toml — add to deals extras
[project.optional-dependencies]
deals = ["apscheduler>=3.10", "requests"]

Acceptance Criteria

  • APScheduler integrated with SQLite job store (persists across restarts)
  • gaia deals watch starts background scheduler with default 6h interval
  • gaia deals watch --interval 2h configurable interval
  • gaia deals watch --stop cleanly shuts down scheduler
  • gaia deals watch --status shows next run time, last run, items tracked
  • Each price check iteration: fetches all watchlist items → calls APIs → records prices
  • Failed checks logged but don't crash the scheduler
  • Scheduler survives agent restarts (job store persistence)
  • Unit tests with mocked scheduler

Phase

Phase 2 — Tracking & Alerts

Dependencies

  • DealAgent base class (Phase 1)
  • Watchlist management (Phase 2)
  • Product search tools (Phase 1)

New Dependencies

Package Version License Purpose
apscheduler >=3.10 MIT Background task scheduling

Metadata

Metadata

Assignees

No one assigned

    Labels

    agentdealsDealAgent: price tracking and deal discoverydomain:automationScheduler, autonomy, RAG, web search, watchers, researchenhancementNew feature or requestp1medium prioritytrack:consumer-appHermes-competitor consumer product — mobile-first, voice + messaging + memory + skills

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions