Skip to content

fal: queue polling realism (IN_QUEUE → IN_PROGRESS → COMPLETED with logs + metrics) #170

@tombeckenham

Description

@tombeckenham

Correction: I filed an earlier version of this issue claiming the fal handler rejected image/video fixtures. That was wrong — I was reading a fork that was behind upstream. The general src/fal.ts from #152 already serves image and video via onFalQueue (RawJSONResponse). Sorry for the noise.

The remaining gap is polling realism.

Problem

falQueueStates stores jobs with status: "COMPLETED" on submit (src/fal.ts post-#152). Status polls always return COMPLETED immediately, with no queue_position, no logs, no metrics.inference_time.

That makes it impossible to exercise client code that polls /status and reacts to intermediate states. Concrete example: openstory's motion-generation.ts:checkMotionStatus polls and branches on IN_QUEUE / IN_PROGRESS (queue position decay, log streaming, latency metrics). End-to-end tests against aimock can't drive that code path.

Proposal

Add MockServerOptions.falQueue: { pollsBeforeInProgress?: number; pollsBeforeCompleted?: number }. When set:

  • Submit creates the job in IN_QUEUE with queue_position.
  • Each /status (or /{id}) poll advances IN_QUEUE → IN_PROGRESS → COMPLETED.
  • Status response includes logs: [{ timestamp, level, message }] (one entry per state transition) and metrics: { inference_time } (wall-clock elapsed since submit) once COMPLETED.
  • Cancel before completion returns 200 { status: "CANCELLED" }; after still returns 400 { status: "ALREADY_COMPLETED" }.
  • Result fetch before completion returns 202 with the current status body (was previously unreachable since jobs always completed instantly).

Defaults stay at 0 / 0 so callers who don't care keep the existing instant-complete behavior — no test churn.

Nice-to-have (separate, can fold in or skip)

Typed sugar helpers onFalImage(prompt, ImageResponse, opts?) and onFalVideo(prompt, VideoResponse, opts?). Mirror the ImageResponse / VideoResponse shapes used by onImage / onVideo and translate to fal's wire envelope under the hood. Strictly ergonomics — onFalQueue already covers the functional need.

PR up at #171.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions