comicbox.formats.base.online.auto_engage

source module comicbox.formats.base.online.auto_engage

Auto-engagement of effort=minimal for large unattended runs.

Comicbox’s online lookup is fast enough on small libraries that the default balanced effort is the right pick. At scale — hundreds of comics against ComicVine — balanced fans out enough per-comic API calls to blow past the documented rate caps and stretch into multi-hour waits.

minimal (Effort.MINIMAL) only cuts cost for sources that FAN OUT per comic — it caps discovery breadth and name-filters candidates before their per-item API call. ComicVine works that way. Metron does NOT: since PR #143 it resolves a comic in a single issues_list(series_name=...) call whose cost is effort-invariant, so auto-engaging minimal for it would be a no-op. Auto-engagement therefore targets fan-out sources only (see _UNATTENDED_THRESHOLDS); single-call sources rely on the rate limiter + retry for pacing, not on effort.

This module’s resolve_auto_engaged_budget watches for two signals, both of which indicate the user is unlikely to want a multi-hour foreground wait:

  • --prompts never + batch size ≥ per-source _UNATTENDED_THRESHOLD
  • stdin is not a TTY + batch size ≥ per-source _NON_TTY_THRESHOLD (4x looser — cron-shaped invocations get the suggestion at a higher bar so manual xargs pipelines don’t surprise the user)

When either fires, the resolved OnlineSettings gets a per-source override pinning effort=minimal for the matching source(s). The user can suppress with a YAML per-source override (online.tuning.per_source.<source>.effort) or by naming any global effort at all — --effort, COMICBOX_ONLINE__TUNING__EFFORT, or online.tuning.effort in a config file. --effort balanced is a choice, not silence, and is honored as one.

Thresholds are placeholders from 06-api-budget-spec.md; Phase B’s calibration data validated the per-source-cap reasoning but didn’t pin the exact curve breakpoints. Revisit when real-world large-library runs surface call patterns.

Functions

source resolve_auto_engaged_budget(online: OnlineSettings, batch_size: int) → OnlineSettings

Return a possibly-modified OnlineSettings with auto-engaged effort.

Inputs

  • online: the resolved config (CLI + env + file).
  • batch_size: total files to process this run, after --recurse expansion. Pass 0 or 1 to disable auto-engagement.

Behavior: walks each known source; for each, if the user did NOT set a per-source override AND named no global effort, check the triggers in order. Per-source override pinned only when at least one trigger fires.

User-set per-source overrides — even to BALANCED — block auto-engagement for that source. Any global effort blocks it everywhere, balanced included: the user has spoken.

Logs an INFO line per source the engagement fires for, so the user sees what’s happening and knows how to override.