-
Event — Base for all workflow events.
-
BatchStarted — Fired once before the first file is submitted.
-
FileShortCircuited — Worker decided the embedded metadata had not changed and skipped parse.
-
FileParsed — Worker fully parsed embedded metadata.
-
FileError — Worker raised an exception.
erroris the str(exception). -
BatchFinished — Fired once after every file has been delivered.
-
SearchStarted — Worker is about to query an online source for this file.
-
SearchCompleted — Online source returned candidate list.
-
AutoWritten — Matcher accepted a candidate without prompting.
-
SeriesIdentified — A series was resolved and cached for series-first batching.
-
PromptQueued — Matcher needs human input; prompt dispatched to PromptHandler.
-
PromptResolved — PromptHandler returned a decision.
-
PromptDeferred — OnlineSession is in defer_prompts mode and queued this prompt for later.
-
PromptResolvedFromCache — OnlineSession auto-applied a cached choice instead of re-prompting.
-
Skipped — Matcher declined to write metadata for this file.
-
NoMatch — No candidate cleared min_confidence.
-
RateLimited — Source signaled a rate-limit hit.
-
FileFinished — Per-file online tagging completed (success, skip, no-match, or error).
comicbox.events¶
source module comicbox.events
Shared event types for read / write / online workflows.
One on_event callback shape across the three public bulk entry points (iter_process_files, bulk_write, OnlineSession.tag_many) so a caller — typically Codex — can wire a single handler.
Handlers run on the orchestrator thread that drains worker results. They must be thread-safe and should return quickly; expensive work belongs in a queue the handler dispatches to.
Classes
source dataclass Event(*, kind: str, path: Path | None = None, index: int | None = None, total: int | None = None)
Base for all workflow events.
Subclasses are concrete frozen dataclasses keyed by the kind literal on the subclass — callers can match on type or on kind.
source dataclass BatchStarted(*, kind: Literal[‘batch_started’] = ‘batch_started’, path: Path | None = None, index: int | None = None, total: int | None = None)
Bases : Event
Fired once before the first file is submitted.
source dataclass FileShortCircuited(*, kind: Literal[‘file_short_circuited’] = ‘file_short_circuited’, path: Path | None = None, index: int | None = None, total: int | None = None, reason: Literal[‘mtime_unchanged’, ‘filtered’, ‘dry_run’] = ‘mtime_unchanged’)
Bases : Event
Worker decided the embedded metadata had not changed and skipped parse.
reason="mtime_unchanged" — embedded mtime <= caller’s old_mtime. reason="filtered" — caller passed full_metadata=False so the worker only collected envelope fields.
source dataclass FileParsed(*, kind: Literal[‘file_parsed’] = ‘file_parsed’, path: Path | None = None, index: int | None = None, total: int | None = None)
Bases : Event
Worker fully parsed embedded metadata.
source dataclass FileError(*, kind: Literal[‘file_error’] = ‘file_error’, path: Path | None = None, index: int | None = None, total: int | None = None, error: str = ‘’)
Bases : Event
Worker raised an exception. error is the str(exception).
source dataclass BatchFinished(*, kind: Literal[‘batch_finished’] = ‘batch_finished’, path: Path | None = None, index: int | None = None, total: int | None = None, parsed: int = 0, short_circuited: int = 0, errored: int = 0)
Bases : Event
Fired once after every file has been delivered.
parsed / short_circuited / errored carry per-outcome counts so callers can render an end-of-batch summary without re-walking the result stream.
source dataclass SearchStarted(*, kind: Literal[‘search_started’] = ‘search_started’, path: Path | None = None, index: int | None = None, total: int | None = None, source: str = ‘’)
Bases : Event
Worker is about to query an online source for this file.
source dataclass SearchCompleted(*, kind: Literal[‘search_completed’] = ‘search_completed’, path: Path | None = None, index: int | None = None, total: int | None = None, source: str = ‘’, n_candidates: int = 0, top_score: float | None = None)
Bases : Event
Online source returned candidate list.
source dataclass AutoWritten(*, kind: Literal[‘auto_written’] = ‘auto_written’, path: Path | None = None, index: int | None = None, total: int | None = None, source: str = ‘’, candidate_summary: str = ‘’)
Bases : Event
Matcher accepted a candidate without prompting.
source dataclass SeriesIdentified(*, kind: Literal[‘series_identified’] = ‘series_identified’, path: Path | None = None, index: int | None = None, total: int | None = None, source: str = ‘’, series_fingerprint: str = ‘’, volume_id: int = 0)
Bases : Event
A series was resolved and cached for series-first batching.
Fired when a cold-path search resolves a series and the session’s series_cache is populated for the first time. Subsequent issues of the same series skip the search via :meth:OnlineSource.lookup_issue.
source dataclass PromptQueued(*, kind: Literal[‘prompt_queued’] = ‘prompt_queued’, path: Path | None = None, index: int | None = None, total: int | None = None, source: str = ‘’, prompt_id: str = ‘’, n_candidates: int = 0)
Bases : Event
Matcher needs human input; prompt dispatched to PromptHandler.
source dataclass PromptResolved(*, kind: Literal[‘prompt_resolved’] = ‘prompt_resolved’, path: Path | None = None, index: int | None = None, total: int | None = None, source: str = ‘’, prompt_id: str = ‘’, action: str = ‘’)
Bases : Event
PromptHandler returned a decision.
source dataclass PromptDeferred(*, kind: Literal[‘prompt_deferred’] = ‘prompt_deferred’, path: Path | None = None, index: int | None = None, total: int | None = None, source: str = ‘’, prompt_id: str = ‘’, fingerprint: str = ‘’, n_candidates: int = 0)
Bases : Event
OnlineSession is in defer_prompts mode and queued this prompt for later.
The batch continues; the deferred prompt is accessible via OnlineSession.deferred_prompts(). Codex’s intended flow: surface these in a “Review tagging” UI after the batch completes, collect the user’s decisions, seed them back into the session’s dedup cache via preload_resolution(), then re-run the affected files.
source dataclass PromptResolvedFromCache(*, kind: Literal[‘prompt_resolved_from_cache’] = ‘prompt_resolved_from_cache’, path: Path | None = None, index: int | None = None, total: int | None = None, source: str = ‘’, prompt_id: str = ‘’, action: str = ‘’, fingerprint: str = ‘’)
Bases : Event
OnlineSession auto-applied a cached choice instead of re-prompting.
Fingerprint matched a previously-resolved prompt in the per-session dedup cache; the user’s handler was not invoked.
source dataclass Skipped(*, kind: Literal[‘skipped’] = ‘skipped’, path: Path | None = None, index: int | None = None, total: int | None = None, source: str = ‘’, reason: str = ‘’)
Bases : Event
Matcher declined to write metadata for this file.
source dataclass NoMatch(*, kind: Literal[‘no_match’] = ‘no_match’, path: Path | None = None, index: int | None = None, total: int | None = None, source: str = ‘’)
Bases : Event
No candidate cleared min_confidence.
source dataclass RateLimited(*, kind: Literal[‘rate_limited’] = ‘rate_limited’, path: Path | None = None, index: int | None = None, total: int | None = None, source: str = ‘’, retry_after_seconds: float | None = None)
Bases : Event
Source signaled a rate-limit hit.
retry_after_seconds is the server hint when available; otherwise the per-source retry-schedule’s next sleep.
source dataclass FileFinished(*, kind: Literal[‘file_finished’] = ‘file_finished’, path: Path | None = None, index: int | None = None, total: int | None = None, outcome: str = ‘’)
Bases : Event
Per-file online tagging completed (success, skip, no-match, or error).