Production Features

June 26, 2026 ยท View on GitHub

Vidify includes operational patterns for long-running video workflows, optional dependencies, and model-serving failures.

Retry with Exponential Backoff

Model calls such as vLLM chat, Whisper ASR, and embedding requests are wrapped with retry handling for transient failures: timeouts, connection errors, 5xx responses, and rate limits.

from agent.core.retry import retry_with_backoff

@retry_with_backoff(max_retries=3, base_delay=2.0, max_delay=60.0)
def my_api_call():
    ...

Graceful Degradation

Optional skills such as OCR, object detection, emotion analysis, translation, and web search use @skill_guard. If an optional dependency is missing or a model call fails, the skill is skipped and the workflow continues with a warning.

This matters because many environments do not have every optional dependency: GPU/NPU runtimes, OCR engines, YOLO weights, internet access, or model-serving endpoints may be unavailable during fast tests.

Parallel Skill Execution

The detailed workflow runs independent skills such as OCR, object detection, and emotion analysis in a thread pool. Configure concurrency in workflows.yaml:

detailed:
  max_parallel_skills: 3

Parallel Segment Processing

For long videos, brief and detailed can split work into temporal segments, process segments concurrently, and merge timestamps back into a unified result.

Long video
  -> split into temporal segments
  -> process frames, captions, OCR, detection, and emotion per segment
  -> adjust timestamps
  -> merge results
  -> build final timeline

Global steps stay global: probing, sufficiency checks, timeline construction, translation, and web search. Segment-local steps include frame sampling, visual captioning, OCR, object detection, and emotion analysis.

Example configuration:

detailed:
  parallel_segments:
    enabled: true
    segment_duration: 300
    max_workers: 4
    min_video_duration: 300
    min_segment_duration: 30
  parallel_asr:
    enabled: true
    max_workers: 4
    segment_duration: 240
    min_audio_duration: 300
    min_segment_duration: 30

Pluggable Segmentation

Segmentation strategies implement BaseSegmentor in agent/core/segment.py. The default DurationSegmentor uses fixed-duration FFmpeg ranges. Custom segmentors can register scene, semantic, or model-based boundaries:

from agent.core.segment import BaseSegmentor, register_segmentor

class SceneSegmentor(BaseSegmentor):
    def segment(self, video_path, duration_sec, base_cache_dir):
        boundaries = my_model.predict(video_path)
        segments = []
        for i, (start, end) in enumerate(boundaries):
            segments.append(self._make_segment(i, start, end, base_cache_dir))
        return self._merge_tiny_tail(segments, duration_sec)

register_segmentor("scene", SceneSegmentor)

Set segmentor_name: scene in config, or pass it to split_video_into_segments().

Progress Events

agent.core.events emits lifecycle events:

Event TypePurpose
skill_startA skill or workflow step started
skill_completeA skill or workflow step completed
skill_errorA skill failed
skill_skippedA guarded optional skill was skipped
progressHuman-readable progress update

The CLI prints progress to stderr. The API exposes progress through POST /analyze/stream as Server-Sent Events.

Lifecycle Hooks

Shell commands can run at workflow milestones through hooks.yaml:

hooks:
  post_analysis:
    - command: "curl -X POST $WEBHOOK_URL -d @$RESULT_PATH"
      async: true
      timeout: 10
  on_error:
    - command: "echo 'Failed: $ERROR_MSG' >> errors.log"

Hook points include pre_analysis, post_analysis, post_skill, on_error, post_highlight, and post_index.

Structured Logging

Pass --log-format json to the CLI for machine-readable logs with fields such as video_id, skill_name, duration_ms, and status.

WorkflowTracker can be used for per-workflow skill timing summaries.