Chuyển tới nội dung chính

Xây dựng Plugin nhà cung cấp tạo video

Các plugin của nhà cung cấp thế hệ video đăng ký một chương trình phụ trợ phục vụ mọi lệnh gọi công cụ `video_generate

. Các nhà cung cấp tích hợp (xAI, FAL) cung cấp dưới dạng phần bổ trợ. Thêm một cái mới hoặc ghi đè một cái được đóng gói bằng cách thả một thư mục vào `plugins/video_gen/<name/

.

mẹo

Các bản sao thế hệ video Image Generation Provider Plugins gần như từng dòng một — nếu bạn đã xây dựng phần phụ trợ thế hệ hình ảnh thì bạn đã biết hình dạng. Điểm khác biệt chính: phương thức quảng cáo/tỷ lệ khung hình/thời lượng của phương pháp capabilities() và quy ước định tuyến (chuyển image_url để sử dụng tính năng chuyển hình ảnh thành video, bỏ qua nó để sử dụng tính năng chuyển văn bản thành video — nhà cung cấp chọn điểm cuối phù hợp trong nội bộ).

Bề mặt thống nhất (một công cụ, hai phương thức)

Công cụ video_generate hiển thị hai phương thức thông qua một tham số:

  • Chuyển văn bản thành video — chỉ gọi bằng `prompt

. Nhà cung cấp định tuyến đến điểm cuối chuyển văn bản thành video.

  • Chuyển hình ảnh thành video — gọi bằng `prompt

`image_url

. Nhà cung cấp định tuyến đến điểm cuối chuyển hình ảnh sang video của mình.

Chỉnh sửa và mở rộng có chủ ý nằm ngoài phạm vi. Hầu hết các phần phụ trợ không hỗ trợ chúng và sự không nhất quán sẽ buộc phần văn xuôi trên mỗi phần phụ trợ phải được đưa vào mô tả công cụ của tác nhân.

Cách hoạt động của tính năng khám phá

Hermes quét các phần phụ trợ của thế hệ video ở ba nơi:

  1. Đi kèm

<repo/plugins/video_gen/<name/ (được tải tự động với kind: backend

) 2. Người dùng

~/.Hermes/plugins/video_gen/<name/ (chọn tham gia qua plugins.enabled

) 3. pip — các gói khai báo điểm vào Hermes_agent.plugins ``Hàm register(ctx) của mỗi plugin gọi ctx.register_video_gen_provider(...)

. Nhà cung cấp đang hoạt động được video_gen.provider chọn trong `config.yaml

; Hermes tools → Video Generation hướng dẫn người dùng lựa chọn. Không giống như `image_generate

, không có chương trình phụ trợ kế thừa trong cây — mọi nhà cung cấp đều là một plugin.

Cấu trúc thư mục

` plugins/video_gen/my-backend/ ├── init.py # VideoGenProvider subclass + register() └── plugin.YAML # Manifest with kind: backend

`

Nhà cung cấp VideoGen ABC

Phân lớp `agent.video_gen_provider.VideoGenProvider

. Bắt buộc: thuộc tính name và phương thức `generate()

.


# plugins/video_gen/my-backend/__init__.py
from typing import Any, Dict, List, Optional
import os`from agent.video_gen_provider import (
VideoGenProvider,
error_response,
success_response,
)

class MyVideoGenProvider(VideoGenProvider):
@property
def name(self) -> str:
return "my-backend"`@property
def display_name(self) -> str:
return "My Backend"`def is_available(self) -> bool:
return bool(os.environ.get("MY_API_KEY"))

def list_models(self) -> List[Dict[str, Any]]:
# Each entry is a model FAMILY — a name the user picks once.
# Your provider's generate() routes within the family based on
# whether image_url was passed.
return [
&#123;
"id": "fast",
"display": "Fast",
"speed": "~30s",
"strengths": "Cheapest tier",
"price": "$0.05/s",
"modalities": ["text", "image"], # advisory
&#125;,
]

def default_model(self) -> Optional[str]:
return "fast"`def capabilities(self) -> Dict[str, Any]:
return &#123;
"modalities": ["text", "image"],
"aspect_ratios": ["16:9", "9:16"],
"resolutions": ["720p", "1080p"],
"min_duration": 1,
"max_duration": 10,
"supports_audio": False,
"supports_negative_prompt": True,
"max_reference_images": 0,
&#125;`def get_setup_schema(self) -> Dict[str, Any]:
return &#123;
"name": "My Backend",
"badge": "paid",
"tag": "Short description shown in
`Hermes tools

",
"env_vars": [
&#123;
"key": "MY_API_KEY",
"prompt": "My Backend API key",
"url": "https://mybackend.example.com/keys",
&#125;,
],
&#125;`def generate(
self,
prompt: str,
*,
model: Optional[str] = None,
image_url: Optional[str] = None,
reference_image_urls: Optional[List[str]] = None,
duration: Optional[int] = None,
aspect_ratio: str = "16:9",
resolution: str = "720p",
negative_prompt: Optional[str] = None,
audio: Optional[bool] = None,
seed: Optional[int] = None,
**kwargs: Any, # always ignore unknown kwargs for forward-compat
) -> Dict[str, Any]:
# ROUTE: image_url presence picks the endpoint.
if image_url:
endpoint = "my-backend/image-to-video"
modality_used = "image"
else:
endpoint = "my-backend/text-to-video"
modality_used = "text"

# ... call your API ...

return success_response(
video="https://your-cdn/output.mp4",
model=model or "fast",
prompt=prompt,
modality=modality_used,
aspect_ratio=aspect_ratio,
duration=duration or 5,
provider=self.name,
)

def register(ctx) -> None:
ctx.register_video_gen_provider(MyVideoGenProvider())

`

## Bản kê khai plugin

``` yaml

# plugins/video_gen/my-backend/plugin.YAML
name: my-backend
version: 1.0.0
description: "My video generation backend"
author: Your Name
kind: backend
requires_env:
- MY_API_KEY

`

## Lược đồ
`video_generate
``Công cụ này hiển thị một lược đồ trên mỗi chương trình phụ trợ. Nhà cung cấp bỏ qua các tham số mà họ không hỗ trợ.

| Tham số | Nó làm gì |
|---|---|
|
`prompt
` | Hướng dẫn bằng văn bản (bắt buộc) |
|
`image_url
` | Khi đặt → chuyển hình ảnh thành video; khi bị bỏ qua → chuyển văn bản thành video |
|
`reference_image_urls
` | Tham chiếu phong cách/ký tự (phụ thuộc vào nhà cung cấp) |
|
`duration
` | Giây — kẹp nhà cung cấp |
|
`aspect_ratio
` |

"16:9"

,

"9:16"

,

"1:1"

, ... — kẹp của nhà cung cấp |
|
`resolution
` |

"480p"
` /

"540p"
` /

"720p"
` /

"1080p"
` — kẹp của nhà cung cấp |
|
`negative_prompt
` | Nội dung cần tránh (chỉ Pixverse/Kling) |
|
`audio
` | Âm thanh gốc (Bậc định giá Veo3 / Pixverse) |
|
`seed
` | Khả năng tái tạo |
|
`model
` | Ghi đè mô hình/gia đình đang hoạt động |

capabilities()
` của nhà cung cấp quảng cáo cái nào trong số này được vinh danh. Tác nhân nhìn thấy các khả năng của chương trình phụ trợ đang hoạt động trong mô tả công cụ, được xây dựng lại một cách linh hoạt khi người dùng thay đổi chương trình phụ trợ thông qua
`Hermes tools

.

## Họ mô hình và định tuyến điểm cuối (mẫu FAL)

Khi phần phụ trợ của bạn có nhiều điểm cuối cho mỗi "mô hình" — như FAL, trong đó mỗi dòng (Veo 3.1, Pixverse v6, Kling O3) có cả

/text-to-video
` và URL

/image-to-video
` — đại diện cho mỗi **dòng** dưới dạng một mục nhập danh mục.
`generate()
` của bạn chọn điểm cuối phù hợp dựa trên việc
`image_url
` có được thông qua hay không:

``` python
FAMILIES = &#123;
"veo3.1": &#123;
"text_endpoint": "fal-ai/veo3.1",
"image_endpoint": "fal-ai/veo3.1/image-to-video",

# ... family-specific capability flags ...
&#125;,
&#125;`def generate(self, prompt, *, image_url=None, model=None, **kwargs):
family_id, family = _resolve_family(model)
endpoint = family["image_endpoint"] if image_url else family["text_endpoint"]
# ... build payload from family's declared capability flags, call endpoint ...

`
``Người dùng chọn
`veo3.1
` một lần trong
`Hermes tools

. Tác nhân không bao giờ nghĩ đến điểm cuối - nó chỉ vượt qua (hoặc không vượt qua)
`image_url

.

## Ưu tiên lựa chọn

Đối với các núm mô hình theo từng phiên bản (xem
`plugins/video_gen/fal/__init__.py

):
1. Từ khóa
`model=
` từ lệnh gọi công cụ
2.

&lt;PROVIDER_VIDEO_MODEL
` env var
3.
`video_gen.&lt;provider.model
` trong
`config.yaml

4.
`video_gen.model
` trong
`config.yaml
` (khi đó là một trong các ID của bạn)
5.
`default_model()
` của nhà cung cấp

## Hình dạng phản hồi``success_response()
` và
`error_response()
` tạo ra hình dạng chính tả mỗi lần trả về phụ trợ. Hãy sử dụng chúng - đừng đưa ra mệnh lệnh bằng tay.Khóa thành công:
`success

,
`video
` (URL hoặc đường dẫn tuyệt đối),
`model

,
`prompt

,
`modality
` (

"text"
` hoặc

"image"

),
`aspect_ratio

,
`duration

,
`provider

, cộng với
`extra

.

Các phím lỗi:
`success

,
`video
` (Không có),
`error

,
`error_type

,
`model

,
`prompt

,
`aspect_ratio

,
`provider

.

## Nơi lưu hiện vật

Nếu chương trình phụ trợ của bạn trả về base64, hãy sử dụng
`save_b64_video()
` để viết theo

$Hermes_HOME/cache/videos/

. Đối với các byte thô từ lần tìm nạp HTTP tiếp theo, hãy sử dụng
`save_bytes_video()

. Nếu không, hãy trả lại trực tiếp URL ngược dòng — cổng sẽ giải quyết các URL từ xa khi phân phối.`##Thử nghiệm

Thả thử nghiệm khói theo
`tests/plugins/video_gen/test_&lt;name_plugin.py

. Các thử nghiệm xAI và FAL hiển thị mẫu - đăng ký, xác minh danh mục, thực hiện định tuyến cả khi có và không có
`image_url

, xác nhận phản hồi lỗi rõ ràng khi thiếu xác thực.