feat(plugins): externalize Vydra provider (#116813)

This commit is contained in:
Vincent Koc
2026-07-31 20:35:43 +08:00
committed by GitHub
parent 08c47c29bb
commit ba1a6722bb
14 changed files with 150 additions and 23 deletions

View File

@@ -51,7 +51,7 @@ Each entry lists the package, distribution route, and description.
## Core npm package
64 plugins
63 plugins
- **[admin-http-rpc](/plugins/reference/admin-http-rpc)** (`@openclaw/admin-http-rpc`) - included in OpenClaw. OpenClaw admin HTTP RPC endpoint.
@@ -169,8 +169,6 @@ Each entry lists the package, distribution route, and description.
- **[volcengine](/plugins/reference/volcengine)** (`@openclaw/volcengine-provider`) - included in OpenClaw. Adds Volcengine, Volcengine Plan model provider support to OpenClaw.
- **[vydra](/plugins/reference/vydra)** (`@openclaw/vydra-provider`) - included in OpenClaw. Adds Vydra model provider support to OpenClaw.
- **[web-readability](/plugins/reference/web-readability)** (`@openclaw/web-readability-plugin`) - included in OpenClaw. Extract readable article content from local HTML web fetch responses.
- **[webhooks](/plugins/reference/webhooks)** (`@openclaw/webhooks`) - included in OpenClaw. Authenticated inbound webhooks that bind external automation to OpenClaw TaskFlows.
@@ -183,7 +181,7 @@ Each entry lists the package, distribution route, and description.
## Official external packages
81 plugins
82 plugins
- **[acpx](/plugins/reference/acpx)** (`@openclaw/acpx`) - npm; ClawHub. OpenClaw ACP runtime backend with plugin-owned session and transport management.
@@ -337,6 +335,8 @@ Each entry lists the package, distribution route, and description.
- **[voyage](/plugins/reference/voyage)** (`@openclaw/voyage-provider`) - npm; ClawHub: `clawhub:@openclaw/voyage-provider`. Adds memory embedding provider support.
- **[vydra](/plugins/reference/vydra)** (`@openclaw/vydra-provider`) - npm; ClawHub: `clawhub:@openclaw/vydra-provider`. Adds Vydra model provider support to OpenClaw.
- **[whatsapp](/plugins/reference/whatsapp)** (`@openclaw/whatsapp`) - ClawHub: `clawhub:@openclaw/whatsapp`; npm. OpenClaw WhatsApp channel plugin for WhatsApp Web chats.
- **[zai](/plugins/reference/zai)** (`@openclaw/zai-provider`) - npm; ClawHub: `clawhub:@openclaw/zai-provider`. Adds Z.AI model provider support to OpenClaw.

View File

@@ -12,7 +12,7 @@ Adds Vydra model provider support to OpenClaw.
## Distribution
- Package: `@openclaw/vydra-provider`
- Install route: included in OpenClaw
- Install route: npm; ClawHub: `clawhub:@openclaw/vydra-provider`
## Surface

View File

@@ -6,7 +6,7 @@ read_when:
title: "Vydra"
---
The bundled Vydra plugin adds:
The official Vydra plugin adds:
- Image generation via `vydra/grok-imagine`
- Video generation via `vydra/veo3` (text-to-video) and `vydra/kling` (image-to-video)
@@ -17,7 +17,7 @@ OpenClaw uses the same `VYDRA_API_KEY` for all three capabilities.
| Property | Value |
| --------------- | ------------------------------------------------------------------------- |
| Provider id | `vydra` |
| Plugin | bundled, `enabledByDefault: true` |
| Plugin | `@openclaw/vydra-provider` |
| Auth env var | `VYDRA_API_KEY` |
| Onboarding flag | `--auth-choice vydra-api-key` |
| Direct CLI flag | `--vydra-api-key <key>` |
@@ -31,6 +31,13 @@ Use `https://www.vydra.ai/api/v1` as the base URL. Vydra's apex host (`https://v
## Setup
<Steps>
<Step title="Install the plugin">
```bash
openclaw plugins install @openclaw/vydra-provider
openclaw gateway restart
```
</Step>
<Step title="Run interactive onboarding">
```bash
openclaw onboard --auth-choice vydra-api-key
@@ -52,7 +59,7 @@ Use `https://www.vydra.ai/api/v1` as the base URL. Vydra's apex host (`https://v
<AccordionGroup>
<Accordion title="Image generation">
Default and only bundled image model:
Default and only Vydra image model:
- `vydra/grok-imagine`
@@ -70,7 +77,7 @@ Use `https://www.vydra.ai/api/v1` as the base URL. Vydra's apex host (`https://v
}
```
Bundled support is text-to-image only, at most one image per request. Vydra's hosted edit routes expect remote image URLs, and the bundled plugin does not add a Vydra-specific upload bridge.
Vydra support is text-to-image only, at most one image per request. Vydra's hosted edit routes expect remote image URLs, and the plugin does not add a Vydra-specific upload bridge.
<Note>
See [Image Generation](/tools/image-generation) for shared tool parameters, provider selection, and failover behavior.
@@ -101,8 +108,8 @@ Use `https://www.vydra.ai/api/v1` as the base URL. Vydra's apex host (`https://v
Notes:
- `vydra/kling` rejects local file uploads up front; only a remote image URL reference works.
- Vydra's `kling` HTTP route has been inconsistent about whether it requires `image_url` or `video_url`; the bundled provider sends the same remote image URL in both fields.
- The bundled plugin stays conservative and does not forward undocumented style knobs such as aspect ratio, resolution, watermark, or generated audio.
- Vydra's `kling` HTTP route has been inconsistent about whether it requires `image_url` or `video_url`; the plugin sends the same remote image URL in both fields.
- The plugin stays conservative and does not forward undocumented style knobs such as aspect ratio, resolution, watermark, or generated audio.
<Note>
See [Video Generation](/tools/video-generation) for shared tool parameters, provider selection, and failover behavior.
@@ -119,7 +126,7 @@ Use `https://www.vydra.ai/api/v1` as the base URL. Vydra's apex host (`https://v
pnpm test:live -- extensions/vydra/vydra.live.test.ts
```
The bundled Vydra live file covers:
The Vydra live file covers:
- `vydra/veo3` text-to-video
- `vydra/kling` image-to-video using a remote image URL
@@ -154,7 +161,7 @@ Use `https://www.vydra.ai/api/v1` as the base URL. Vydra's apex host (`https://v
- Model: `elevenlabs/tts`
- Voice id: `21m00Tcm4TlvDq8ikWAM` ("Rachel")
The bundled plugin exposes this one known-good default voice and returns MP3 audio files.
The plugin exposes this one known-good default voice and returns MP3 audio files.
</Accordion>
</AccordionGroup>

View File

@@ -146,7 +146,7 @@ the shared live sweep:
| Qwen | ✓ | ✓ | ✓ | `generate`, `imageToVideo`; `videoToVideo` skipped because this provider needs remote `http(s)` video URLs |
| Runway | ✓ | ✓ | ✓ | `generate`, `imageToVideo`; `videoToVideo` runs only when the selected model is `runway/gen4_aleph` |
| Together | ✓ | ✓ | - | `generate`, `imageToVideo` |
| Vydra | ✓ | ✓ | - | `generate`; shared `imageToVideo` skipped because bundled `veo3` is text-only and bundled `kling` requires a remote image URL |
| Vydra | ✓ | ✓ | - | `generate`; shared `imageToVideo` skipped because `veo3` is text-only and `kling` requires a remote image URL |
| xAI | ✓ | ✓ | ✓ | Classic supports all modes; Video 1.5 is image-to-video only; remote MP4 input keeps `videoToVideo` out of the shared sweep |
## Tool parameters
@@ -416,7 +416,7 @@ Automatic fallback across authenticated providers is always enabled. A per-call
</Accordion>
<Accordion title="Vydra">
Uses `https://www.vydra.ai/api/v1` directly to avoid auth-dropping
redirects. `veo3` is bundled as text-to-video only; `kling` requires
redirects. `veo3` is text-to-video only; `kling` requires
a remote image URL.
</Accordion>
<Accordion title="xAI">

View File

@@ -0,0 +1,13 @@
# OpenClaw Vydra Provider
Official OpenClaw provider plugin for Vydra image, video, and speech generation.
Install from OpenClaw:
```bash
openclaw plugins install @openclaw/vydra-provider
openclaw gateway restart
```
Set `VYDRA_API_KEY`, then configure an image, video, or speech model. See
<https://docs.openclaw.ai/providers/vydra> for capability details and examples.

View File

@@ -47,7 +47,7 @@ export function buildVydraImageGenerationProvider(): ImageGenerationProvider {
async generateImage(req) {
if ((req.inputImages?.length ?? 0) > 0) {
throw new Error(
"Vydra image generation currently supports text-to-image only in the bundled plugin.",
"Vydra image generation currently supports text-to-image only in the Vydra plugin.",
);
}
if ((req.count ?? 1) > 1) {

View File

@@ -11,7 +11,7 @@ const PROVIDER_ID = "vydra";
export default definePluginEntry({
id: PROVIDER_ID,
name: "Vydra Provider",
description: "Bundled Vydra image, video, and speech provider",
description: "Vydra image, video, and speech provider",
register(api) {
api.registerProvider({
id: PROVIDER_ID,

View File

@@ -1,8 +1,11 @@
{
"name": "@openclaw/vydra-provider",
"version": "2026.7.2",
"private": true,
"description": "OpenClaw Vydra media provider plugin",
"description": "OpenClaw Vydra media provider plugin.",
"repository": {
"type": "git",
"url": "https://github.com/openclaw/openclaw"
},
"type": "module",
"devDependencies": {
"@openclaw/plugin-sdk": "workspace:*"
@@ -10,6 +13,23 @@
"openclaw": {
"extensions": [
"./index.ts"
]
],
"install": {
"clawhubSpec": "clawhub:@openclaw/vydra-provider",
"npmSpec": "@openclaw/vydra-provider",
"defaultChoice": "npm",
"minHostVersion": ">=2026.7.2"
},
"compat": {
"pluginApi": ">=2026.7.2"
},
"build": {
"openclawVersion": "2026.7.2",
"bundledDist": false
},
"release": {
"publishToClawHub": true,
"publishToNpm": true
}
}
}

View File

@@ -44,9 +44,7 @@ function resolveVydraVideoRequestBody(
};
}
if ((req.inputImages?.length ?? 0) > 0) {
throw new Error(
`Vydra ${model} does not support image reference inputs in the bundled plugin.`,
);
throw new Error(`Vydra ${model} does not support image reference inputs in the Vydra plugin.`);
}
return {
model,

View File

@@ -317,6 +317,7 @@
"!dist/extensions/vercel-ai-gateway/**",
"!dist/extensions/voice-call/**",
"!dist/extensions/voyage/**",
"!dist/extensions/vydra/**",
"!dist/extensions/whatsapp/**",
"!dist/extensions/zai/**",
"!dist/extensions/zalo/**",

View File

@@ -1528,6 +1528,66 @@
}
}
},
{
"name": "@openclaw/vydra-provider",
"description": "OpenClaw Vydra media provider plugin.",
"source": "official",
"kind": "provider",
"openclaw": {
"plugin": {
"id": "vydra",
"label": "Vydra"
},
"providers": [
{
"id": "vydra",
"name": "Vydra",
"docs": "/providers/vydra",
"categories": [
"cloud",
"media"
],
"envVars": [
"VYDRA_API_KEY"
],
"authChoices": [
{
"method": "api-key",
"choiceId": "vydra-api-key",
"choiceLabel": "Vydra API key",
"groupId": "vydra",
"groupLabel": "Vydra",
"groupHint": "Image, video, and speech",
"optionKey": "vydraApiKey",
"cliFlag": "--vydra-api-key",
"cliOption": "--vydra-api-key <key>",
"cliDescription": "Vydra API key",
"onboardingScopes": [
"image-generation"
]
}
]
}
],
"contracts": {
"speechProviders": [
"vydra"
],
"imageGenerationProviders": [
"vydra"
],
"videoGenerationProviders": [
"vydra"
]
},
"install": {
"clawhubSpec": "clawhub:@openclaw/vydra-provider",
"npmSpec": "@openclaw/vydra-provider",
"defaultChoice": "npm",
"minHostVersion": ">=2026.7.2"
}
}
},
{
"name": "@openclaw/zai-provider",
"description": "OpenClaw Z.AI provider plugin",

View File

@@ -169,6 +169,7 @@ describe("listPersistedBundledPluginLocationBridges", () => {
["synthetic", "@openclaw/synthetic-provider", true],
["teams-meetings", "@openclaw/teams-meetings", true],
["voyage", "@openclaw/voyage-provider", true],
["vydra", "@openclaw/vydra-provider", true],
["zoom-meetings", "@openclaw/zoom-meetings", true],
] as const)(
"externalizes the shipped bundled %s plugin using official install metadata",

View File

@@ -2020,6 +2020,25 @@ describe("official external plugin catalog", () => {
]);
});
it("lists Vydra as an official external media provider", () => {
const vydra = expectCatalogEntry("vydra");
const manifest = getOfficialExternalPluginCatalogManifest(vydra);
expect(resolveOfficialExternalPluginId(vydra)).toBe("vydra");
expect(resolveOfficialExternalPluginInstall(vydra)).toEqual({
clawhubSpec: "clawhub:@openclaw/vydra-provider",
npmSpec: "@openclaw/vydra-provider",
defaultChoice: "npm",
minHostVersion: ">=2026.7.2",
});
expect(manifest?.providers?.map((provider) => provider.id)).toEqual(["vydra"]);
expect(manifest?.contracts).toMatchObject({
speechProviders: ["vydra"],
imageGenerationProviders: ["vydra"],
videoGenerationProviders: ["vydra"],
});
});
it.each([
["teams-meetings", "@openclaw/teams-meetings", "teams_meetings", "teams"],
["zoom-meetings", "@openclaw/zoom-meetings", "zoom_meetings", "zoom"],

View File

@@ -349,6 +349,14 @@ describe("bundled plugin build entries", () => {
}
});
it("excludes the externalized Vydra provider from bundled artifacts", () => {
const artifacts = listBundledPluginPackArtifacts();
expect(artifacts).not.toContain("dist/extensions/vydra/index.js");
expect(artifacts).not.toContain("dist/extensions/vydra/openclaw.plugin.json");
expect(artifacts).not.toContain("dist/extensions/vydra/package.json");
});
it("excludes externalized meeting plugins from bundled artifacts", () => {
const artifacts = listBundledPluginPackArtifacts();