> ## Documentation Index
> Fetch the complete documentation index at: https://docs.veadk.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Video generation

## Overview

Tool identifier `video_generate`.

`video_generate` generates videos from text. The example below first uses `image_generate` to create a first and last frame, then composes a video.

Import path: `from veadk.tools.builtin_tools.video_generate import video_generate`

## Environment & prerequisites

<Warning>
  Requirements:

  1. Configure the API key for the agent's reasoning model.
  2. Configure the video-generation model name (`MODEL_VIDEO_NAME`).
  3. If composing from a first/last frame, also configure the image-generation model name (`MODEL_IMAGE_NAME`).
</Warning>

Environment variables:

* `MODEL_VIDEO_API_KEY`: API key for the video-generation model; falls back to `MODEL_AGENT_API_KEY` and then to `model.api_key` from the config file when unset
* `MODEL_AGENT_API_KEY`: API key for the agent's reasoning model
* `MODEL_VIDEO_NAME`: video-generation model name
* `MODEL_VIDEO_API_BASE`: video-generation model API endpoint; defaults to the ModelArk endpoint
* `MODEL_IMAGE_NAME`: image-generation model name

<Note>
  Credentials are resolved at tool execution time, not at import time. Importing the tool module does not initialize a client or require credentials to be present.
</Note>

`config.yaml` keys:

```yaml title="config.yaml" lines theme={null}
model:
  video:
    name: doubao-seedance-2-0-260128
    api_base: https://ark.cn-beijing.volces.com/api/v3/
    api_key: your-api-key-here
```

For BytePlus, explicitly configure the media model name, API base URL, and key for your enabled service. Do not assume `CLOUD_PROVIDER` overrides media configuration. Capabilities and parameter limits depend on the selected model service. The video API base and default model name are resolved at import time; configure them before starting the process.

## Usage

```python title="examples/tools/video_generate/agent.py" lines theme={null}
import asyncio

from veadk import Agent, Runner
from veadk.memory.short_term_memory import ShortTermMemory
from veadk.tools.builtin_tools.image_generate import image_generate
from veadk.tools.builtin_tools.video_generate import video_generate, video_task_query

agent = Agent(
    name="video_generate_agent",
    model_name="doubao-seed-2-1-pro-260628",
    description="An expert in creating images and videos.",
    instruction=(
        "First use image_generate to create a first frame and a last frame, then use "
        "video_generate to compose a video. Query pending tasks with video_task_query, "
        "then return the completed video URL and summarize its content."
    ),
    tools=[image_generate, video_generate, video_task_query],
)

runner = Runner(agent=agent, short_term_memory=ShortTermMemory())


async def main():
    response = await runner.run(
        "Generate a puppy, then a scene of it flying into the sky, and finally compose a video"
    )
    print(response)


if __name__ == "__main__":
    asyncio.run(main())
```

## Parameters and task states

| Parameter | Type | Default | Description |
| :- | :- | :- | :- |
| `params` | `list[dict]` | Required | Video generation requests |
| `tool_context` | `ToolContext` | Injected | Invocation context |
| `batch_size` | `int` | `10` | Requests submitted per batch; use a positive integer |
| `max_wait_seconds` | `int` | `1200` | Per-batch polling budget used to determine poll rounds, not a strict end-to-end timeout |
| `model_name` | `str` | Configured or built-in model | Generation model; its default is read at import time |

Each request requires `video_name: str` and `prompt: str`. Other fields use service defaults when omitted:

| Field | Type | Default | Description |
| :- | :- | :- | :- |
| `first_frame`, `last_frame` | `str \| None` | `None` | First and last frame image URLs |
| `reference_images` | `list[str]` | `[]` | Reference images |
| `reference_videos` | `list[str]` | `[]` | Reference videos |
| `reference_audios` | `list[str]` | `[]` | Reference audio |
| `ratio`, `resolution` | `str \| None` | `None` | Aspect ratio and resolution supported by the selected model |
| `duration`, `frames` | `int \| None` | `None` | Duration in seconds or frame count, subject to model constraints |
| `camera_fixed` | `bool \| None` | `None` | Fixed camera |
| `seed` | `int \| None` | `None` | Random seed |
| `watermark` | `bool \| None` | `None` | Add a watermark |
| `generate_audio` | `bool \| None` | `None` | Generate audio where supported |
| `tools` | `list[dict] \| None` | `None` | For example web search; text-only generation supports it, while reference inputs cause it to be ignored |

Results contain `status`, `success_list`, `error_list`, `error_details`, and `pending_list`. Success items map video names to URLs. Pending items include a `task_id`. Ending local waiting does not cancel remote generation; query the existing task instead of resubmitting it.

`video_task_query(task_id: str, tool_context: ToolContext)` requires the task ID and injected context, with no optional arguments. It returns fields including `status`, `video_url`, and `error`. `queued` and `running` are still in progress; deliver a video only after `succeeded` with a URL. Inspect errors for `failed` tasks. Query using the same service endpoint and authorized credentials as generation.
