Versely

    Background tasks while you keep chatting

    Long renders don't have to freeze the conversation. How to hand a slow multi-step job to a background task and keep briefing the agent on the next scene.

    Versely Team9 min read

    Most people use an AI agent the way they'd use a vending machine: ask, wait, collect, ask again. That's fine when a request takes four seconds. It's a bad deal when the request is "generate five product images, assemble them into a reel, and post it," because now you are sitting in a chat window watching a progress indicator for several minutes with nothing to do, and the next three things you were going to ask for are queued behind a job that doesn't need your attention.

    Versely's spawn_background_task exists precisely to break that dependency. It takes a multi-step job, runs it asynchronously with real-time progress, and leaves the conversation open. You keep talking. The job keeps running. Neither one is waiting on the other.

    What belongs in the background

    The tool's own threshold is jobs that take more than about 30 seconds, and the shapes it names are specific: movie creation with music, slideshow-to-reel pipelines, bulk generation, generate-then-post workflows, and anything that combines several generations into one outcome.

    That's a more useful filter than "long things." The common property isn't duration, it's whether the job needs you between its steps. A single image generation is short and needs nothing from you, so foregrounding it is fine. A five-scene movie with a music bed and a caption pass is long and self-directing once briefed, which makes it the ideal candidate to hand off. The jobs that don't belong in the background are the ones where step two depends on your judgement about step one, because a background task will happily proceed past the decision you wanted to make.

    There's also a scheduling dimension. scheduled_at lets a task start at a future time instead of immediately, which turns "run this in the background" into "run this tomorrow at 8am" without any extra machinery. Automating a multi-step content task covers the full shape of what a task can contain.

    Name it once, correctly

    This is the part that has a downstream cost if you get it wrong, and it's easy to get wrong because it looks cosmetic.

    Every background task also auto-creates a reusable saved workflow, keyed on the task name. So the name you pick isn't a label for this run. It's the identity of a recipe you'll be re-running for months. The guidance is explicit about the failure mode: use a clean, intent-based name like "Instagram Vlog with Captions", not a run-specific one like "Vlog Rerun v2". Name it after the run and you end up with a workflow list full of near-duplicates that all do roughly the same thing, none of which is obviously the canonical one.

    The second field that matters is workflow_theme. On a first run it looks redundant, because you just described everything in the steps. It isn't. The theme is what future re-runs anchor to. Without it, a re-run has nothing stable to hold onto and the output drifts away from the thing you originally approved. Supply it on the first spawn and the recipe stays on-brief the fifth time you run it.

    Field What it's for What happens if you skip it
    task_name Identity of the auto-saved workflow Duplicate near-identical workflows pile up
    workflow_theme Stable creative brief for re-runs Re-runs drift off the original brief
    scheduled_at Future start time Task starts immediately
    media_assets Your own files, referenced by steps Steps have nothing to point at

    Uploaded files attached to a task are referenced from inside the steps rather than pasted in as URLs, which is what lets the same recipe run again against different inputs later. That's also the reason saving and reusing a video workflow is worth thinking about at spawn time rather than after the fact.

    What you do with the foreground

    Here's the actual parallel-work pattern, and it's less about the tool than about how you sequence your own thinking.

    While a task is running, the most valuable thing you can do in the conversation is prepare its successor. Not idle chat, not status-checking. Concretely, in a single session:

    1. Spawn the slow job first. Whatever has the longest tail goes in the background immediately, before you refine anything else. If it needs a lot of steps, that's an argument for starting it sooner, not later.
    2. Brief the next scene while it runs. Describe shot two, iterate the prompt, look at a reference, argue with the agent about the framing. None of this is blocked.
    3. Do the cheap decisions in the gap. Caption style, aspect ratio, music direction. These are decisions that cost nothing to make and cost real time if you make them after the render lands.
    4. Collect and spawn again. When the first task reports back, you already know what the second one is, so the gap between them is seconds instead of a fresh planning conversation.

    Run this way and the session's wall-clock time is roughly the length of your slowest job, not the sum of all of them. Run it the vending-machine way and it's the sum.

    One caveat worth stating plainly: the agent is one conversation, and a background task's steps were fixed when you spawned it. Changing your mind mid-run doesn't retroactively change what's already dispatched. If the brief changes materially, stop the run rather than hoping the tail of it absorbs the update.

    Checking in without babysitting

    The reason people foreground long jobs isn't impatience, it's fear of losing them. That fear is mostly unfounded here, and there are four specific tools that replace it:

    • check_generation_status queries the real status of pending images, videos and audio rather than guessing from what scrolled past in chat. Worth calling before you conclude anything is stuck.
    • list_workflow_runs returns your recent video workflow runs with run IDs, statuses and timestamps, capped at ten. Run IDs are persistent, which means a run you can't find in the chat scrollback is not a lost run.
    • resume_workflow_run finds scenes stuck in a generating state past a staleness window (ten minutes by default), resets the earliest stuck one, and kicks the scheduler. It no-ops safely on a healthy run, so there's no penalty for checking speculatively.
    • stop_workflow_run cancels a run outright and flips every in-flight scene to cancelled so it stops consuming dispatcher time. Scenes that already finished stay intact.

    Checking or resuming a stuck workflow run is the fuller version of this. The practical rule: check status when you have a reason to, not on a two-minute loop.

    A background task can also end with a push notification via send_notification, which arrives even when the app is backgrounded. That's the piece that makes true parallel work possible, because it means you don't have to keep the tab in front of you to know the job finished.

    Before you spawn: check the balance

    Multi-step tasks have a specific failure mode that single generations don't: partial completion. Four steps succeed, the fifth finds an empty balance, and you're left holding an incomplete pipeline plus the spend on the steps that did run.

    check_credits exists for exactly this and is worth calling before any long chain, not after. estimate_cost goes a step further and prices a planned set of generations up front, using the same pricing logic as real charges, so you can see the total before dispatching anything. Checking your credits before generating is a ten-second habit that prevents the most annoying class of background-task failure. Costs are per step, summed across the task, and the cost reference pages break down what specific job shapes come to.

    A session that actually runs in parallel

    "Run this in the background: generate four kitchen-scene product shots, animate the best one, add a music bed, and notify me when it's done. Call the workflow 'Kitchen Product Reel' and keep the theme as warm daylight home-kitchen product demo."

    That's one spawn with a clean intent-based name and a theme that will hold across re-runs. The conversation stays live. Immediately after:

    "While that runs — I want a second version of this for the outdoor set. Let's work the prompt now."

    Nothing about this is blocked. When the notification lands, the second brief is already written and the next spawn is one message away. Later, re-running it doesn't require re-describing anything, because the first spawn already saved the recipe.

    FAQ

    Can I keep generating things normally while a background task runs?

    Yes. That's the point of the tool. The task runs asynchronously with its own progress reporting, and the conversation stays fully usable for anything else, including other generations. The one thing to keep in mind is that both are drawing on the same credit balance, so a big background job plus heavy foreground work can add up faster than either would alone.

    What happens if I close the app while a task is running?

    The task keeps running. It's server-side, not tied to your session. Anything running as a video workflow comes back under list_workflow_runs with a persistent run ID and its current status; for plain image, video or audio jobs, check_generation_status is the one to ask. Adding a send_notification step at the end means you'll hear about completion even with the app backgrounded.

    How do I tell a genuinely stuck run from a slow one?

    Look at the staleness window rather than total elapsed time. resume_workflow_run treats a scene as stuck when its last update is older than ten minutes by default, which is a more reliable signal than "this feels slow." Calling it on a healthy run is a no-op, so there's no penalty for checking.

    Should every long job be a background task?

    No. If step two depends on you judging step one, foreground it and stay in the loop. Background tasks are for jobs that are self-directing once briefed. The tell is whether you'd have anything to say between the steps. If you would, don't hand the whole chain over at once.