feat: add video generation core infrastructure and extend image generation parameters (#53681)

* feat: add video generation core infrastructure and extend image generation parameters

Add full video generation capability to OpenClaw core:

- New `video_generate` agent tool with support for prompt, duration, aspect ratio,
  resolution, seed, watermark, I2V (first/last frame), camerafixed, and draft mode
- New `VideoGenerationProvider` plugin SDK type and `registerVideoGenerationProvider` API
- New `src/video-generation/` module (types, runtime with fallback, provider registry)
- New `openclaw/plugin-sdk/video-generation` export for external plugins
- 200MB max file size for generated videos (vs default 5MB for images)

Extend image generation with additional parameters:
- `seed`, `watermark`, `guidanceScale`, `optimizePrompt`, `providerOptions`
- New `readBooleanParam()` helper in tool common utilities

Update plugin registry, contracts, and all test mocks to include
`videoGenerationProviders` and `videoGenerationProviderIds`.

Made-with: Cursor

* fix: validate aspect ratio against target provider when model override is set

* cleanup: remove redundant ?? undefined from video/image generate tools

* chore: regenerate plugin SDK API baseline after video generation additions

---------

Co-authored-by: yongliang.xie <yongliang.xie@bytedance.com>
This commit is contained in:
xieyongliang
2026-03-26 09:45:06 +08:00
committed by GitHub
parent 39fbfd9b28
commit 4cb8dde894
37 changed files with 1380 additions and 241 deletions

View File

@@ -352,7 +352,7 @@
"exportName": "ImageGenerationProvider",
"kind": "type",
"source": {
"line": 66,
"line": 72,
"path": "src/image-generation/types.ts"
}
},
@@ -379,7 +379,7 @@
"exportName": "ImageGenerationResult",
"kind": "type",
"source": {
"line": 36,
"line": 42,
"path": "src/image-generation/types.ts"
}
},
@@ -397,7 +397,7 @@
"exportName": "MediaUnderstandingProviderPlugin",
"kind": "type",
"source": {
"line": 951,
"line": 952,
"path": "src/plugins/types.ts"
}
},
@@ -415,7 +415,7 @@
"exportName": "OpenClawPluginApi",
"kind": "type",
"source": {
"line": 1314,
"line": 1316,
"path": "src/plugins/types.ts"
}
},
@@ -424,7 +424,7 @@
"exportName": "OpenClawPluginConfigSchema",
"kind": "type",
"source": {
"line": 88,
"line": 89,
"path": "src/plugins/types.ts"
}
},
@@ -433,7 +433,7 @@
"exportName": "PluginLogger",
"kind": "type",
"source": {
"line": 59,
"line": 60,
"path": "src/plugins/types.ts"
}
},
@@ -451,7 +451,7 @@
"exportName": "ProviderAuthContext",
"kind": "type",
"source": {
"line": 155,
"line": 156,
"path": "src/plugins/types.ts"
}
},
@@ -460,7 +460,7 @@
"exportName": "ProviderAuthResult",
"kind": "type",
"source": {
"line": 140,
"line": 141,
"path": "src/plugins/types.ts"
}
},
@@ -469,7 +469,7 @@
"exportName": "ProviderRuntimeModel",
"kind": "type",
"source": {
"line": 295,
"line": 296,
"path": "src/plugins/types.ts"
}
},
@@ -523,7 +523,7 @@
"exportName": "SpeechProviderPlugin",
"kind": "type",
"source": {
"line": 933,
"line": 934,
"path": "src/plugins/types.ts"
}
},
@@ -3396,7 +3396,7 @@
"exportName": "MediaUnderstandingProviderPlugin",
"kind": "type",
"source": {
"line": 951,
"line": 952,
"path": "src/plugins/types.ts"
}
},
@@ -3414,7 +3414,7 @@
"exportName": "OpenClawPluginApi",
"kind": "type",
"source": {
"line": 1314,
"line": 1316,
"path": "src/plugins/types.ts"
}
},
@@ -3423,7 +3423,7 @@
"exportName": "OpenClawPluginCommandDefinition",
"kind": "type",
"source": {
"line": 1068,
"line": 1070,
"path": "src/plugins/types.ts"
}
},
@@ -3432,7 +3432,7 @@
"exportName": "OpenClawPluginConfigSchema",
"kind": "type",
"source": {
"line": 88,
"line": 89,
"path": "src/plugins/types.ts"
}
},
@@ -3441,7 +3441,7 @@
"exportName": "OpenClawPluginDefinition",
"kind": "type",
"source": {
"line": 1296,
"line": 1298,
"path": "src/plugins/types.ts"
}
},
@@ -3450,7 +3450,7 @@
"exportName": "OpenClawPluginService",
"kind": "type",
"source": {
"line": 1285,
"line": 1287,
"path": "src/plugins/types.ts"
}
},
@@ -3459,7 +3459,7 @@
"exportName": "OpenClawPluginServiceContext",
"kind": "type",
"source": {
"line": 1277,
"line": 1279,
"path": "src/plugins/types.ts"
}
},
@@ -3468,7 +3468,7 @@
"exportName": "OpenClawPluginToolContext",
"kind": "type",
"source": {
"line": 103,
"line": 104,
"path": "src/plugins/types.ts"
}
},
@@ -3477,7 +3477,7 @@
"exportName": "OpenClawPluginToolFactory",
"kind": "type",
"source": {
"line": 120,
"line": 121,
"path": "src/plugins/types.ts"
}
},
@@ -3486,7 +3486,7 @@
"exportName": "PluginCommandContext",
"kind": "type",
"source": {
"line": 966,
"line": 968,
"path": "src/plugins/types.ts"
}
},
@@ -3495,7 +3495,7 @@
"exportName": "PluginInteractiveTelegramHandlerContext",
"kind": "type",
"source": {
"line": 1097,
"line": 1099,
"path": "src/plugins/types.ts"
}
},
@@ -3504,7 +3504,7 @@
"exportName": "PluginLogger",
"kind": "type",
"source": {
"line": 59,
"line": 60,
"path": "src/plugins/types.ts"
}
},
@@ -3522,7 +3522,7 @@
"exportName": "ProviderAugmentModelCatalogContext",
"kind": "type",
"source": {
"line": 571,
"line": 572,
"path": "src/plugins/types.ts"
}
},
@@ -3531,7 +3531,7 @@
"exportName": "ProviderAuthContext",
"kind": "type",
"source": {
"line": 155,
"line": 156,
"path": "src/plugins/types.ts"
}
},
@@ -3540,7 +3540,7 @@
"exportName": "ProviderAuthDoctorHintContext",
"kind": "type",
"source": {
"line": 446,
"line": 447,
"path": "src/plugins/types.ts"
}
},
@@ -3549,7 +3549,7 @@
"exportName": "ProviderAuthMethod",
"kind": "type",
"source": {
"line": 233,
"line": 234,
"path": "src/plugins/types.ts"
}
},
@@ -3558,7 +3558,7 @@
"exportName": "ProviderAuthMethodNonInteractiveContext",
"kind": "type",
"source": {
"line": 217,
"line": 218,
"path": "src/plugins/types.ts"
}
},
@@ -3567,7 +3567,7 @@
"exportName": "ProviderAuthResult",
"kind": "type",
"source": {
"line": 140,
"line": 141,
"path": "src/plugins/types.ts"
}
},
@@ -3576,7 +3576,7 @@
"exportName": "ProviderBuildMissingAuthMessageContext",
"kind": "type",
"source": {
"line": 499,
"line": 500,
"path": "src/plugins/types.ts"
}
},
@@ -3585,7 +3585,7 @@
"exportName": "ProviderBuiltInModelSuppressionContext",
"kind": "type",
"source": {
"line": 515,
"line": 516,
"path": "src/plugins/types.ts"
}
},
@@ -3594,7 +3594,7 @@
"exportName": "ProviderBuiltInModelSuppressionResult",
"kind": "type",
"source": {
"line": 524,
"line": 525,
"path": "src/plugins/types.ts"
}
},
@@ -3603,7 +3603,7 @@
"exportName": "ProviderCacheTtlEligibilityContext",
"kind": "type",
"source": {
"line": 487,
"line": 488,
"path": "src/plugins/types.ts"
}
},
@@ -3612,7 +3612,7 @@
"exportName": "ProviderCatalogContext",
"kind": "type",
"source": {
"line": 254,
"line": 255,
"path": "src/plugins/types.ts"
}
},
@@ -3621,7 +3621,7 @@
"exportName": "ProviderCatalogResult",
"kind": "type",
"source": {
"line": 277,
"line": 278,
"path": "src/plugins/types.ts"
}
},
@@ -3630,7 +3630,7 @@
"exportName": "ProviderDefaultThinkingPolicyContext",
"kind": "type",
"source": {
"line": 548,
"line": 549,
"path": "src/plugins/types.ts"
}
},
@@ -3639,7 +3639,7 @@
"exportName": "ProviderDiscoveryContext",
"kind": "type",
"source": {
"line": 587,
"line": 588,
"path": "src/plugins/types.ts"
}
},
@@ -3648,7 +3648,7 @@
"exportName": "ProviderFetchUsageSnapshotContext",
"kind": "type",
"source": {
"line": 427,
"line": 428,
"path": "src/plugins/types.ts"
}
},
@@ -3657,7 +3657,7 @@
"exportName": "ProviderModernModelPolicyContext",
"kind": "type",
"source": {
"line": 558,
"line": 559,
"path": "src/plugins/types.ts"
}
},
@@ -3666,7 +3666,7 @@
"exportName": "ProviderNormalizeResolvedModelContext",
"kind": "type",
"source": {
"line": 338,
"line": 339,
"path": "src/plugins/types.ts"
}
},
@@ -3675,7 +3675,7 @@
"exportName": "ProviderPreparedRuntimeAuth",
"kind": "type",
"source": {
"line": 374,
"line": 375,
"path": "src/plugins/types.ts"
}
},
@@ -3684,7 +3684,7 @@
"exportName": "ProviderPrepareDynamicModelContext",
"kind": "type",
"source": {
"line": 329,
"line": 330,
"path": "src/plugins/types.ts"
}
},
@@ -3693,7 +3693,7 @@
"exportName": "ProviderPrepareExtraParamsContext",
"kind": "type",
"source": {
"line": 460,
"line": 461,
"path": "src/plugins/types.ts"
}
},
@@ -3702,7 +3702,7 @@
"exportName": "ProviderPrepareRuntimeAuthContext",
"kind": "type",
"source": {
"line": 353,
"line": 354,
"path": "src/plugins/types.ts"
}
},
@@ -3711,7 +3711,7 @@
"exportName": "ProviderResolvedUsageAuth",
"kind": "type",
"source": {
"line": 414,
"line": 415,
"path": "src/plugins/types.ts"
}
},
@@ -3720,7 +3720,7 @@
"exportName": "ProviderResolveDynamicModelContext",
"kind": "type",
"source": {
"line": 312,
"line": 313,
"path": "src/plugins/types.ts"
}
},
@@ -3729,7 +3729,7 @@
"exportName": "ProviderResolveUsageAuthContext",
"kind": "type",
"source": {
"line": 395,
"line": 396,
"path": "src/plugins/types.ts"
}
},
@@ -3738,7 +3738,7 @@
"exportName": "ProviderRuntimeModel",
"kind": "type",
"source": {
"line": 295,
"line": 296,
"path": "src/plugins/types.ts"
}
},
@@ -3747,7 +3747,7 @@
"exportName": "ProviderThinkingPolicyContext",
"kind": "type",
"source": {
"line": 536,
"line": 537,
"path": "src/plugins/types.ts"
}
},
@@ -3765,7 +3765,7 @@
"exportName": "ProviderWrapStreamFnContext",
"kind": "type",
"source": {
"line": 477,
"line": 478,
"path": "src/plugins/types.ts"
}
},
@@ -3810,7 +3810,7 @@
"exportName": "SpeechProviderPlugin",
"kind": "type",
"source": {
"line": 933,
"line": 934,
"path": "src/plugins/types.ts"
}
},
@@ -3902,7 +3902,7 @@
"exportName": "MediaUnderstandingProviderPlugin",
"kind": "type",
"source": {
"line": 951,
"line": 952,
"path": "src/plugins/types.ts"
}
},
@@ -3920,7 +3920,7 @@
"exportName": "OpenClawPluginApi",
"kind": "type",
"source": {
"line": 1314,
"line": 1316,
"path": "src/plugins/types.ts"
}
},
@@ -3929,7 +3929,7 @@
"exportName": "OpenClawPluginCommandDefinition",
"kind": "type",
"source": {
"line": 1068,
"line": 1070,
"path": "src/plugins/types.ts"
}
},
@@ -3938,7 +3938,7 @@
"exportName": "OpenClawPluginConfigSchema",
"kind": "type",
"source": {
"line": 88,
"line": 89,
"path": "src/plugins/types.ts"
}
},
@@ -3947,7 +3947,7 @@
"exportName": "OpenClawPluginDefinition",
"kind": "type",
"source": {
"line": 1296,
"line": 1298,
"path": "src/plugins/types.ts"
}
},
@@ -3956,7 +3956,7 @@
"exportName": "OpenClawPluginService",
"kind": "type",
"source": {
"line": 1285,
"line": 1287,
"path": "src/plugins/types.ts"
}
},
@@ -3965,7 +3965,7 @@
"exportName": "OpenClawPluginServiceContext",
"kind": "type",
"source": {
"line": 1277,
"line": 1279,
"path": "src/plugins/types.ts"
}
},
@@ -3974,7 +3974,7 @@
"exportName": "PluginCommandContext",
"kind": "type",
"source": {
"line": 966,
"line": 968,
"path": "src/plugins/types.ts"
}
},
@@ -3983,7 +3983,7 @@
"exportName": "PluginInteractiveTelegramHandlerContext",
"kind": "type",
"source": {
"line": 1097,
"line": 1099,
"path": "src/plugins/types.ts"
}
},
@@ -3992,7 +3992,7 @@
"exportName": "PluginLogger",
"kind": "type",
"source": {
"line": 59,
"line": 60,
"path": "src/plugins/types.ts"
}
},
@@ -4001,7 +4001,7 @@
"exportName": "ProviderAugmentModelCatalogContext",
"kind": "type",
"source": {
"line": 571,
"line": 572,
"path": "src/plugins/types.ts"
}
},
@@ -4010,7 +4010,7 @@
"exportName": "ProviderAuthContext",
"kind": "type",
"source": {
"line": 155,
"line": 156,
"path": "src/plugins/types.ts"
}
},
@@ -4019,7 +4019,7 @@
"exportName": "ProviderAuthDoctorHintContext",
"kind": "type",
"source": {
"line": 446,
"line": 447,
"path": "src/plugins/types.ts"
}
},
@@ -4028,7 +4028,7 @@
"exportName": "ProviderAuthMethod",
"kind": "type",
"source": {
"line": 233,
"line": 234,
"path": "src/plugins/types.ts"
}
},
@@ -4037,7 +4037,7 @@
"exportName": "ProviderAuthMethodNonInteractiveContext",
"kind": "type",
"source": {
"line": 217,
"line": 218,
"path": "src/plugins/types.ts"
}
},
@@ -4046,7 +4046,7 @@
"exportName": "ProviderAuthResult",
"kind": "type",
"source": {
"line": 140,
"line": 141,
"path": "src/plugins/types.ts"
}
},
@@ -4055,7 +4055,7 @@
"exportName": "ProviderBuildMissingAuthMessageContext",
"kind": "type",
"source": {
"line": 499,
"line": 500,
"path": "src/plugins/types.ts"
}
},
@@ -4064,7 +4064,7 @@
"exportName": "ProviderBuiltInModelSuppressionContext",
"kind": "type",
"source": {
"line": 515,
"line": 516,
"path": "src/plugins/types.ts"
}
},
@@ -4073,7 +4073,7 @@
"exportName": "ProviderBuiltInModelSuppressionResult",
"kind": "type",
"source": {
"line": 524,
"line": 525,
"path": "src/plugins/types.ts"
}
},
@@ -4082,7 +4082,7 @@
"exportName": "ProviderCacheTtlEligibilityContext",
"kind": "type",
"source": {
"line": 487,
"line": 488,
"path": "src/plugins/types.ts"
}
},
@@ -4091,7 +4091,7 @@
"exportName": "ProviderCatalogContext",
"kind": "type",
"source": {
"line": 254,
"line": 255,
"path": "src/plugins/types.ts"
}
},
@@ -4100,7 +4100,7 @@
"exportName": "ProviderCatalogResult",
"kind": "type",
"source": {
"line": 277,
"line": 278,
"path": "src/plugins/types.ts"
}
},
@@ -4109,7 +4109,7 @@
"exportName": "ProviderDefaultThinkingPolicyContext",
"kind": "type",
"source": {
"line": 548,
"line": 549,
"path": "src/plugins/types.ts"
}
},
@@ -4118,7 +4118,7 @@
"exportName": "ProviderDiscoveryContext",
"kind": "type",
"source": {
"line": 587,
"line": 588,
"path": "src/plugins/types.ts"
}
},
@@ -4127,7 +4127,7 @@
"exportName": "ProviderFetchUsageSnapshotContext",
"kind": "type",
"source": {
"line": 427,
"line": 428,
"path": "src/plugins/types.ts"
}
},
@@ -4136,7 +4136,7 @@
"exportName": "ProviderModernModelPolicyContext",
"kind": "type",
"source": {
"line": 558,
"line": 559,
"path": "src/plugins/types.ts"
}
},
@@ -4145,7 +4145,7 @@
"exportName": "ProviderNormalizeResolvedModelContext",
"kind": "type",
"source": {
"line": 338,
"line": 339,
"path": "src/plugins/types.ts"
}
},
@@ -4154,7 +4154,7 @@
"exportName": "ProviderPreparedRuntimeAuth",
"kind": "type",
"source": {
"line": 374,
"line": 375,
"path": "src/plugins/types.ts"
}
},
@@ -4163,7 +4163,7 @@
"exportName": "ProviderPrepareDynamicModelContext",
"kind": "type",
"source": {
"line": 329,
"line": 330,
"path": "src/plugins/types.ts"
}
},
@@ -4172,7 +4172,7 @@
"exportName": "ProviderPrepareExtraParamsContext",
"kind": "type",
"source": {
"line": 460,
"line": 461,
"path": "src/plugins/types.ts"
}
},
@@ -4181,7 +4181,7 @@
"exportName": "ProviderPrepareRuntimeAuthContext",
"kind": "type",
"source": {
"line": 353,
"line": 354,
"path": "src/plugins/types.ts"
}
},
@@ -4190,7 +4190,7 @@
"exportName": "ProviderResolvedUsageAuth",
"kind": "type",
"source": {
"line": 414,
"line": 415,
"path": "src/plugins/types.ts"
}
},
@@ -4199,7 +4199,7 @@
"exportName": "ProviderResolveDynamicModelContext",
"kind": "type",
"source": {
"line": 312,
"line": 313,
"path": "src/plugins/types.ts"
}
},
@@ -4208,7 +4208,7 @@
"exportName": "ProviderResolveUsageAuthContext",
"kind": "type",
"source": {
"line": 395,
"line": 396,
"path": "src/plugins/types.ts"
}
},
@@ -4217,7 +4217,7 @@
"exportName": "ProviderRuntimeModel",
"kind": "type",
"source": {
"line": 295,
"line": 296,
"path": "src/plugins/types.ts"
}
},
@@ -4226,7 +4226,7 @@
"exportName": "ProviderThinkingPolicyContext",
"kind": "type",
"source": {
"line": 536,
"line": 537,
"path": "src/plugins/types.ts"
}
},
@@ -4235,7 +4235,7 @@
"exportName": "ProviderWrapStreamFnContext",
"kind": "type",
"source": {
"line": 477,
"line": 478,
"path": "src/plugins/types.ts"
}
},
@@ -4244,7 +4244,7 @@
"exportName": "SpeechProviderPlugin",
"kind": "type",
"source": {
"line": 933,
"line": 934,
"path": "src/plugins/types.ts"
}
}

View File

@@ -37,26 +37,26 @@
{"declaration":"export type DiagnosticEventPayload = DiagnosticEventPayload;","entrypoint":"index","exportName":"DiagnosticEventPayload","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":150,"sourcePath":"src/infra/diagnostic-events.ts"}
{"declaration":"export type GeneratedImageAsset = GeneratedImageAsset;","entrypoint":"index","exportName":"GeneratedImageAsset","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":4,"sourcePath":"src/image-generation/types.ts"}
{"declaration":"export type HookEntry = HookEntry;","entrypoint":"index","exportName":"HookEntry","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":47,"sourcePath":"src/hooks/types.ts"}
{"declaration":"export type ImageGenerationProvider = ImageGenerationProvider;","entrypoint":"index","exportName":"ImageGenerationProvider","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":66,"sourcePath":"src/image-generation/types.ts"}
{"declaration":"export type ImageGenerationProvider = ImageGenerationProvider;","entrypoint":"index","exportName":"ImageGenerationProvider","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":72,"sourcePath":"src/image-generation/types.ts"}
{"declaration":"export type ImageGenerationRequest = ImageGenerationRequest;","entrypoint":"index","exportName":"ImageGenerationRequest","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":21,"sourcePath":"src/image-generation/types.ts"}
{"declaration":"export type ImageGenerationResolution = ImageGenerationResolution;","entrypoint":"index","exportName":"ImageGenerationResolution","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":12,"sourcePath":"src/image-generation/types.ts"}
{"declaration":"export type ImageGenerationResult = ImageGenerationResult;","entrypoint":"index","exportName":"ImageGenerationResult","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":36,"sourcePath":"src/image-generation/types.ts"}
{"declaration":"export type ImageGenerationResult = ImageGenerationResult;","entrypoint":"index","exportName":"ImageGenerationResult","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":42,"sourcePath":"src/image-generation/types.ts"}
{"declaration":"export type ImageGenerationSourceImage = ImageGenerationSourceImage;","entrypoint":"index","exportName":"ImageGenerationSourceImage","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":14,"sourcePath":"src/image-generation/types.ts"}
{"declaration":"export type MediaUnderstandingProviderPlugin = MediaUnderstandingProvider;","entrypoint":"index","exportName":"MediaUnderstandingProviderPlugin","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":951,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type MediaUnderstandingProviderPlugin = MediaUnderstandingProvider;","entrypoint":"index","exportName":"MediaUnderstandingProviderPlugin","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":952,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawConfig = OpenClawConfig;","entrypoint":"index","exportName":"OpenClawConfig","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":32,"sourcePath":"src/config/types.openclaw.ts"}
{"declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"index","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":1314,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginConfigSchema = OpenClawPluginConfigSchema;","entrypoint":"index","exportName":"OpenClawPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":88,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type PluginLogger = PluginLogger;","entrypoint":"index","exportName":"PluginLogger","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":59,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"index","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":1316,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginConfigSchema = OpenClawPluginConfigSchema;","entrypoint":"index","exportName":"OpenClawPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":89,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type PluginLogger = PluginLogger;","entrypoint":"index","exportName":"PluginLogger","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":60,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"index","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":54,"sourcePath":"src/plugins/runtime/types.ts"}
{"declaration":"export type ProviderAuthContext = ProviderAuthContext;","entrypoint":"index","exportName":"ProviderAuthContext","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":155,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthResult = ProviderAuthResult;","entrypoint":"index","exportName":"ProviderAuthResult","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":140,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderRuntimeModel = ProviderRuntimeModel;","entrypoint":"index","exportName":"ProviderRuntimeModel","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":295,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthContext = ProviderAuthContext;","entrypoint":"index","exportName":"ProviderAuthContext","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":156,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthResult = ProviderAuthResult;","entrypoint":"index","exportName":"ProviderAuthResult","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":141,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderRuntimeModel = ProviderRuntimeModel;","entrypoint":"index","exportName":"ProviderRuntimeModel","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":296,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ReplyPayload = ReplyPayload;","entrypoint":"index","exportName":"ReplyPayload","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":76,"sourcePath":"src/auto-reply/types.ts"}
{"declaration":"export type RuntimeEnv = RuntimeEnv;","entrypoint":"index","exportName":"RuntimeEnv","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":4,"sourcePath":"src/runtime.ts"}
{"declaration":"export type RuntimeLogger = RuntimeLogger;","entrypoint":"index","exportName":"RuntimeLogger","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":7,"sourcePath":"src/plugins/runtime/types-core.ts"}
{"declaration":"export type SecretInput = SecretInput;","entrypoint":"index","exportName":"SecretInput","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":16,"sourcePath":"src/config/types.secrets.ts"}
{"declaration":"export type SecretRef = SecretRef;","entrypoint":"index","exportName":"SecretRef","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":10,"sourcePath":"src/config/types.secrets.ts"}
{"declaration":"export type SpeechProviderPlugin = SpeechProviderPlugin;","entrypoint":"index","exportName":"SpeechProviderPlugin","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":933,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type SpeechProviderPlugin = SpeechProviderPlugin;","entrypoint":"index","exportName":"SpeechProviderPlugin","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":934,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type StatefulBindingTargetDescriptor = StatefulBindingTargetDescriptor;","entrypoint":"index","exportName":"StatefulBindingTargetDescriptor","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":17,"sourcePath":"src/channels/plugins/binding-types.ts"}
{"declaration":"export type StatefulBindingTargetDriver = StatefulBindingTargetDriver;","entrypoint":"index","exportName":"StatefulBindingTargetDriver","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":15,"sourcePath":"src/channels/plugins/stateful-target-drivers.ts"}
{"declaration":"export type StatefulBindingTargetReadyResult = StatefulBindingTargetReadyResult;","entrypoint":"index","exportName":"StatefulBindingTargetReadyResult","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":7,"sourcePath":"src/channels/plugins/stateful-target-drivers.ts"}
@@ -373,53 +373,53 @@
{"declaration":"export type ChannelPlugin = ChannelPlugin<ResolvedAccount, Probe, Audit>;","entrypoint":"core","exportName":"ChannelPlugin","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":55,"sourcePath":"src/channels/plugins/types.plugin.ts"}
{"declaration":"export type GatewayBindUrlResult = GatewayBindUrlResult;","entrypoint":"core","exportName":"GatewayBindUrlResult","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":1,"sourcePath":"src/shared/gateway-bind-url.ts"}
{"declaration":"export type GatewayRequestHandlerOptions = GatewayRequestHandlerOptions;","entrypoint":"core","exportName":"GatewayRequestHandlerOptions","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":112,"sourcePath":"src/gateway/server-methods/types.ts"}
{"declaration":"export type MediaUnderstandingProviderPlugin = MediaUnderstandingProvider;","entrypoint":"core","exportName":"MediaUnderstandingProviderPlugin","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":951,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type MediaUnderstandingProviderPlugin = MediaUnderstandingProvider;","entrypoint":"core","exportName":"MediaUnderstandingProviderPlugin","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":952,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawConfig = OpenClawConfig;","entrypoint":"core","exportName":"OpenClawConfig","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":32,"sourcePath":"src/config/types.openclaw.ts"}
{"declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":1314,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"core","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":1068,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginConfigSchema = OpenClawPluginConfigSchema;","entrypoint":"core","exportName":"OpenClawPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":88,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"core","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":1296,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginService = OpenClawPluginService;","entrypoint":"core","exportName":"OpenClawPluginService","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":1285,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginServiceContext = OpenClawPluginServiceContext;","entrypoint":"core","exportName":"OpenClawPluginServiceContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":1277,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginToolContext = OpenClawPluginToolContext;","entrypoint":"core","exportName":"OpenClawPluginToolContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":103,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginToolFactory = OpenClawPluginToolFactory;","entrypoint":"core","exportName":"OpenClawPluginToolFactory","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":120,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"core","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":966,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type PluginInteractiveTelegramHandlerContext = PluginInteractiveTelegramHandlerContext;","entrypoint":"core","exportName":"PluginInteractiveTelegramHandlerContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":1097,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type PluginLogger = PluginLogger;","entrypoint":"core","exportName":"PluginLogger","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":59,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":1316,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"core","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":1070,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginConfigSchema = OpenClawPluginConfigSchema;","entrypoint":"core","exportName":"OpenClawPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":89,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"core","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":1298,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginService = OpenClawPluginService;","entrypoint":"core","exportName":"OpenClawPluginService","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":1287,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginServiceContext = OpenClawPluginServiceContext;","entrypoint":"core","exportName":"OpenClawPluginServiceContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":1279,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginToolContext = OpenClawPluginToolContext;","entrypoint":"core","exportName":"OpenClawPluginToolContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":104,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginToolFactory = OpenClawPluginToolFactory;","entrypoint":"core","exportName":"OpenClawPluginToolFactory","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":121,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"core","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":968,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type PluginInteractiveTelegramHandlerContext = PluginInteractiveTelegramHandlerContext;","entrypoint":"core","exportName":"PluginInteractiveTelegramHandlerContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":1099,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type PluginLogger = PluginLogger;","entrypoint":"core","exportName":"PluginLogger","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":60,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"core","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":54,"sourcePath":"src/plugins/runtime/types.ts"}
{"declaration":"export type ProviderAugmentModelCatalogContext = ProviderAugmentModelCatalogContext;","entrypoint":"core","exportName":"ProviderAugmentModelCatalogContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":571,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthContext = ProviderAuthContext;","entrypoint":"core","exportName":"ProviderAuthContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":155,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthDoctorHintContext = ProviderAuthDoctorHintContext;","entrypoint":"core","exportName":"ProviderAuthDoctorHintContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":446,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthMethod = ProviderAuthMethod;","entrypoint":"core","exportName":"ProviderAuthMethod","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":233,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthMethodNonInteractiveContext = ProviderAuthMethodNonInteractiveContext;","entrypoint":"core","exportName":"ProviderAuthMethodNonInteractiveContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":217,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthResult = ProviderAuthResult;","entrypoint":"core","exportName":"ProviderAuthResult","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":140,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderBuildMissingAuthMessageContext = ProviderBuildMissingAuthMessageContext;","entrypoint":"core","exportName":"ProviderBuildMissingAuthMessageContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":499,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderBuiltInModelSuppressionContext = ProviderBuiltInModelSuppressionContext;","entrypoint":"core","exportName":"ProviderBuiltInModelSuppressionContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":515,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderBuiltInModelSuppressionResult = ProviderBuiltInModelSuppressionResult;","entrypoint":"core","exportName":"ProviderBuiltInModelSuppressionResult","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":524,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderCacheTtlEligibilityContext = ProviderCacheTtlEligibilityContext;","entrypoint":"core","exportName":"ProviderCacheTtlEligibilityContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":487,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderCatalogContext = ProviderCatalogContext;","entrypoint":"core","exportName":"ProviderCatalogContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":254,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderCatalogResult = ProviderCatalogResult;","entrypoint":"core","exportName":"ProviderCatalogResult","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":277,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderDefaultThinkingPolicyContext = ProviderDefaultThinkingPolicyContext;","entrypoint":"core","exportName":"ProviderDefaultThinkingPolicyContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":548,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderDiscoveryContext = ProviderCatalogContext;","entrypoint":"core","exportName":"ProviderDiscoveryContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":587,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderFetchUsageSnapshotContext = ProviderFetchUsageSnapshotContext;","entrypoint":"core","exportName":"ProviderFetchUsageSnapshotContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":427,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderModernModelPolicyContext = ProviderModernModelPolicyContext;","entrypoint":"core","exportName":"ProviderModernModelPolicyContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":558,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderNormalizeResolvedModelContext = ProviderNormalizeResolvedModelContext;","entrypoint":"core","exportName":"ProviderNormalizeResolvedModelContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":338,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderPreparedRuntimeAuth = ProviderPreparedRuntimeAuth;","entrypoint":"core","exportName":"ProviderPreparedRuntimeAuth","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":374,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderPrepareDynamicModelContext = ProviderResolveDynamicModelContext;","entrypoint":"core","exportName":"ProviderPrepareDynamicModelContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":329,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderPrepareExtraParamsContext = ProviderPrepareExtraParamsContext;","entrypoint":"core","exportName":"ProviderPrepareExtraParamsContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":460,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderPrepareRuntimeAuthContext = ProviderPrepareRuntimeAuthContext;","entrypoint":"core","exportName":"ProviderPrepareRuntimeAuthContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":353,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderResolvedUsageAuth = ProviderResolvedUsageAuth;","entrypoint":"core","exportName":"ProviderResolvedUsageAuth","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":414,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderResolveDynamicModelContext = ProviderResolveDynamicModelContext;","entrypoint":"core","exportName":"ProviderResolveDynamicModelContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":312,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderResolveUsageAuthContext = ProviderResolveUsageAuthContext;","entrypoint":"core","exportName":"ProviderResolveUsageAuthContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":395,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderRuntimeModel = ProviderRuntimeModel;","entrypoint":"core","exportName":"ProviderRuntimeModel","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":295,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderThinkingPolicyContext = ProviderThinkingPolicyContext;","entrypoint":"core","exportName":"ProviderThinkingPolicyContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":536,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAugmentModelCatalogContext = ProviderAugmentModelCatalogContext;","entrypoint":"core","exportName":"ProviderAugmentModelCatalogContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":572,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthContext = ProviderAuthContext;","entrypoint":"core","exportName":"ProviderAuthContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":156,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthDoctorHintContext = ProviderAuthDoctorHintContext;","entrypoint":"core","exportName":"ProviderAuthDoctorHintContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":447,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthMethod = ProviderAuthMethod;","entrypoint":"core","exportName":"ProviderAuthMethod","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":234,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthMethodNonInteractiveContext = ProviderAuthMethodNonInteractiveContext;","entrypoint":"core","exportName":"ProviderAuthMethodNonInteractiveContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":218,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthResult = ProviderAuthResult;","entrypoint":"core","exportName":"ProviderAuthResult","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":141,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderBuildMissingAuthMessageContext = ProviderBuildMissingAuthMessageContext;","entrypoint":"core","exportName":"ProviderBuildMissingAuthMessageContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":500,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderBuiltInModelSuppressionContext = ProviderBuiltInModelSuppressionContext;","entrypoint":"core","exportName":"ProviderBuiltInModelSuppressionContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":516,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderBuiltInModelSuppressionResult = ProviderBuiltInModelSuppressionResult;","entrypoint":"core","exportName":"ProviderBuiltInModelSuppressionResult","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":525,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderCacheTtlEligibilityContext = ProviderCacheTtlEligibilityContext;","entrypoint":"core","exportName":"ProviderCacheTtlEligibilityContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":488,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderCatalogContext = ProviderCatalogContext;","entrypoint":"core","exportName":"ProviderCatalogContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":255,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderCatalogResult = ProviderCatalogResult;","entrypoint":"core","exportName":"ProviderCatalogResult","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":278,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderDefaultThinkingPolicyContext = ProviderDefaultThinkingPolicyContext;","entrypoint":"core","exportName":"ProviderDefaultThinkingPolicyContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":549,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderDiscoveryContext = ProviderCatalogContext;","entrypoint":"core","exportName":"ProviderDiscoveryContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":588,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderFetchUsageSnapshotContext = ProviderFetchUsageSnapshotContext;","entrypoint":"core","exportName":"ProviderFetchUsageSnapshotContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":428,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderModernModelPolicyContext = ProviderModernModelPolicyContext;","entrypoint":"core","exportName":"ProviderModernModelPolicyContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":559,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderNormalizeResolvedModelContext = ProviderNormalizeResolvedModelContext;","entrypoint":"core","exportName":"ProviderNormalizeResolvedModelContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":339,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderPreparedRuntimeAuth = ProviderPreparedRuntimeAuth;","entrypoint":"core","exportName":"ProviderPreparedRuntimeAuth","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":375,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderPrepareDynamicModelContext = ProviderResolveDynamicModelContext;","entrypoint":"core","exportName":"ProviderPrepareDynamicModelContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":330,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderPrepareExtraParamsContext = ProviderPrepareExtraParamsContext;","entrypoint":"core","exportName":"ProviderPrepareExtraParamsContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":461,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderPrepareRuntimeAuthContext = ProviderPrepareRuntimeAuthContext;","entrypoint":"core","exportName":"ProviderPrepareRuntimeAuthContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":354,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderResolvedUsageAuth = ProviderResolvedUsageAuth;","entrypoint":"core","exportName":"ProviderResolvedUsageAuth","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":415,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderResolveDynamicModelContext = ProviderResolveDynamicModelContext;","entrypoint":"core","exportName":"ProviderResolveDynamicModelContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":313,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderResolveUsageAuthContext = ProviderResolveUsageAuthContext;","entrypoint":"core","exportName":"ProviderResolveUsageAuthContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":396,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderRuntimeModel = ProviderRuntimeModel;","entrypoint":"core","exportName":"ProviderRuntimeModel","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":296,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderThinkingPolicyContext = ProviderThinkingPolicyContext;","entrypoint":"core","exportName":"ProviderThinkingPolicyContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":537,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderUsageSnapshot = ProviderUsageSnapshot;","entrypoint":"core","exportName":"ProviderUsageSnapshot","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":7,"sourcePath":"src/infra/provider-usage.types.ts"}
{"declaration":"export type ProviderWrapStreamFnContext = ProviderWrapStreamFnContext;","entrypoint":"core","exportName":"ProviderWrapStreamFnContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":477,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderWrapStreamFnContext = ProviderWrapStreamFnContext;","entrypoint":"core","exportName":"ProviderWrapStreamFnContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":478,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type RoutePeer = RoutePeer;","entrypoint":"core","exportName":"RoutePeer","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":21,"sourcePath":"src/routing/resolve-route.ts"}
{"declaration":"export type RoutePeerKind = ChatType;","entrypoint":"core","exportName":"RoutePeerKind","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":19,"sourcePath":"src/routing/resolve-route.ts"}
{"declaration":"export type SecretFileReadOptions = SecretFileReadOptions;","entrypoint":"core","exportName":"SecretFileReadOptions","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":7,"sourcePath":"src/infra/secret-file.ts"}
{"declaration":"export type SecretFileReadResult = SecretFileReadResult;","entrypoint":"core","exportName":"SecretFileReadResult","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":12,"sourcePath":"src/infra/secret-file.ts"}
{"declaration":"export type SpeechProviderPlugin = SpeechProviderPlugin;","entrypoint":"core","exportName":"SpeechProviderPlugin","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":933,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type SpeechProviderPlugin = SpeechProviderPlugin;","entrypoint":"core","exportName":"SpeechProviderPlugin","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":934,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type TailscaleStatusCommandResult = TailscaleStatusCommandResult;","entrypoint":"core","exportName":"TailscaleStatusCommandResult","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":1,"sourcePath":"src/shared/tailscale-status.ts"}
{"declaration":"export type TailscaleStatusCommandRunner = TailscaleStatusCommandRunner;","entrypoint":"core","exportName":"TailscaleStatusCommandRunner","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":6,"sourcePath":"src/shared/tailscale-status.ts"}
{"declaration":"export type UsageProviderId = UsageProviderId;","entrypoint":"core","exportName":"UsageProviderId","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":20,"sourcePath":"src/infra/provider-usage.types.ts"}
@@ -429,45 +429,45 @@
{"declaration":"export function definePluginEntry({ id, name, description, kind, configSchema, register, }: DefinePluginEntryOptions): DefinedPluginEntry;","entrypoint":"plugin-entry","exportName":"definePluginEntry","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export","sourceLine":88,"sourcePath":"src/plugin-sdk/plugin-entry.ts"}
{"declaration":"export function emptyPluginConfigSchema(): OpenClawPluginConfigSchema;","entrypoint":"plugin-entry","exportName":"emptyPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export","sourceLine":13,"sourcePath":"src/plugins/config-schema.ts"}
{"declaration":"export type AnyAgentTool = AnyAgentTool;","entrypoint":"plugin-entry","exportName":"AnyAgentTool","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":9,"sourcePath":"src/agents/tools/common.ts"}
{"declaration":"export type MediaUnderstandingProviderPlugin = MediaUnderstandingProvider;","entrypoint":"plugin-entry","exportName":"MediaUnderstandingProviderPlugin","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":951,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type MediaUnderstandingProviderPlugin = MediaUnderstandingProvider;","entrypoint":"plugin-entry","exportName":"MediaUnderstandingProviderPlugin","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":952,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawConfig = OpenClawConfig;","entrypoint":"plugin-entry","exportName":"OpenClawConfig","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":32,"sourcePath":"src/config/types.openclaw.ts"}
{"declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-entry","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":1314,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"plugin-entry","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":1068,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginConfigSchema = OpenClawPluginConfigSchema;","entrypoint":"plugin-entry","exportName":"OpenClawPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":88,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"plugin-entry","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":1296,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginService = OpenClawPluginService;","entrypoint":"plugin-entry","exportName":"OpenClawPluginService","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":1285,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginServiceContext = OpenClawPluginServiceContext;","entrypoint":"plugin-entry","exportName":"OpenClawPluginServiceContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":1277,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"plugin-entry","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":966,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type PluginInteractiveTelegramHandlerContext = PluginInteractiveTelegramHandlerContext;","entrypoint":"plugin-entry","exportName":"PluginInteractiveTelegramHandlerContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":1097,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type PluginLogger = PluginLogger;","entrypoint":"plugin-entry","exportName":"PluginLogger","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":59,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAugmentModelCatalogContext = ProviderAugmentModelCatalogContext;","entrypoint":"plugin-entry","exportName":"ProviderAugmentModelCatalogContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":571,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthContext = ProviderAuthContext;","entrypoint":"plugin-entry","exportName":"ProviderAuthContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":155,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthDoctorHintContext = ProviderAuthDoctorHintContext;","entrypoint":"plugin-entry","exportName":"ProviderAuthDoctorHintContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":446,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthMethod = ProviderAuthMethod;","entrypoint":"plugin-entry","exportName":"ProviderAuthMethod","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":233,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthMethodNonInteractiveContext = ProviderAuthMethodNonInteractiveContext;","entrypoint":"plugin-entry","exportName":"ProviderAuthMethodNonInteractiveContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":217,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthResult = ProviderAuthResult;","entrypoint":"plugin-entry","exportName":"ProviderAuthResult","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":140,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderBuildMissingAuthMessageContext = ProviderBuildMissingAuthMessageContext;","entrypoint":"plugin-entry","exportName":"ProviderBuildMissingAuthMessageContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":499,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderBuiltInModelSuppressionContext = ProviderBuiltInModelSuppressionContext;","entrypoint":"plugin-entry","exportName":"ProviderBuiltInModelSuppressionContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":515,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderBuiltInModelSuppressionResult = ProviderBuiltInModelSuppressionResult;","entrypoint":"plugin-entry","exportName":"ProviderBuiltInModelSuppressionResult","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":524,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderCacheTtlEligibilityContext = ProviderCacheTtlEligibilityContext;","entrypoint":"plugin-entry","exportName":"ProviderCacheTtlEligibilityContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":487,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderCatalogContext = ProviderCatalogContext;","entrypoint":"plugin-entry","exportName":"ProviderCatalogContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":254,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderCatalogResult = ProviderCatalogResult;","entrypoint":"plugin-entry","exportName":"ProviderCatalogResult","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":277,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderDefaultThinkingPolicyContext = ProviderDefaultThinkingPolicyContext;","entrypoint":"plugin-entry","exportName":"ProviderDefaultThinkingPolicyContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":548,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderDiscoveryContext = ProviderCatalogContext;","entrypoint":"plugin-entry","exportName":"ProviderDiscoveryContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":587,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderFetchUsageSnapshotContext = ProviderFetchUsageSnapshotContext;","entrypoint":"plugin-entry","exportName":"ProviderFetchUsageSnapshotContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":427,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderModernModelPolicyContext = ProviderModernModelPolicyContext;","entrypoint":"plugin-entry","exportName":"ProviderModernModelPolicyContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":558,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderNormalizeResolvedModelContext = ProviderNormalizeResolvedModelContext;","entrypoint":"plugin-entry","exportName":"ProviderNormalizeResolvedModelContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":338,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderPreparedRuntimeAuth = ProviderPreparedRuntimeAuth;","entrypoint":"plugin-entry","exportName":"ProviderPreparedRuntimeAuth","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":374,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderPrepareDynamicModelContext = ProviderResolveDynamicModelContext;","entrypoint":"plugin-entry","exportName":"ProviderPrepareDynamicModelContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":329,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderPrepareExtraParamsContext = ProviderPrepareExtraParamsContext;","entrypoint":"plugin-entry","exportName":"ProviderPrepareExtraParamsContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":460,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderPrepareRuntimeAuthContext = ProviderPrepareRuntimeAuthContext;","entrypoint":"plugin-entry","exportName":"ProviderPrepareRuntimeAuthContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":353,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderResolvedUsageAuth = ProviderResolvedUsageAuth;","entrypoint":"plugin-entry","exportName":"ProviderResolvedUsageAuth","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":414,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderResolveDynamicModelContext = ProviderResolveDynamicModelContext;","entrypoint":"plugin-entry","exportName":"ProviderResolveDynamicModelContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":312,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderResolveUsageAuthContext = ProviderResolveUsageAuthContext;","entrypoint":"plugin-entry","exportName":"ProviderResolveUsageAuthContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":395,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderRuntimeModel = ProviderRuntimeModel;","entrypoint":"plugin-entry","exportName":"ProviderRuntimeModel","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":295,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderThinkingPolicyContext = ProviderThinkingPolicyContext;","entrypoint":"plugin-entry","exportName":"ProviderThinkingPolicyContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":536,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderWrapStreamFnContext = ProviderWrapStreamFnContext;","entrypoint":"plugin-entry","exportName":"ProviderWrapStreamFnContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":477,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type SpeechProviderPlugin = SpeechProviderPlugin;","entrypoint":"plugin-entry","exportName":"SpeechProviderPlugin","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":933,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-entry","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":1316,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"plugin-entry","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":1070,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginConfigSchema = OpenClawPluginConfigSchema;","entrypoint":"plugin-entry","exportName":"OpenClawPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":89,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"plugin-entry","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":1298,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginService = OpenClawPluginService;","entrypoint":"plugin-entry","exportName":"OpenClawPluginService","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":1287,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type OpenClawPluginServiceContext = OpenClawPluginServiceContext;","entrypoint":"plugin-entry","exportName":"OpenClawPluginServiceContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":1279,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"plugin-entry","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":968,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type PluginInteractiveTelegramHandlerContext = PluginInteractiveTelegramHandlerContext;","entrypoint":"plugin-entry","exportName":"PluginInteractiveTelegramHandlerContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":1099,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type PluginLogger = PluginLogger;","entrypoint":"plugin-entry","exportName":"PluginLogger","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":60,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAugmentModelCatalogContext = ProviderAugmentModelCatalogContext;","entrypoint":"plugin-entry","exportName":"ProviderAugmentModelCatalogContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":572,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthContext = ProviderAuthContext;","entrypoint":"plugin-entry","exportName":"ProviderAuthContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":156,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthDoctorHintContext = ProviderAuthDoctorHintContext;","entrypoint":"plugin-entry","exportName":"ProviderAuthDoctorHintContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":447,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthMethod = ProviderAuthMethod;","entrypoint":"plugin-entry","exportName":"ProviderAuthMethod","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":234,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthMethodNonInteractiveContext = ProviderAuthMethodNonInteractiveContext;","entrypoint":"plugin-entry","exportName":"ProviderAuthMethodNonInteractiveContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":218,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderAuthResult = ProviderAuthResult;","entrypoint":"plugin-entry","exportName":"ProviderAuthResult","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":141,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderBuildMissingAuthMessageContext = ProviderBuildMissingAuthMessageContext;","entrypoint":"plugin-entry","exportName":"ProviderBuildMissingAuthMessageContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":500,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderBuiltInModelSuppressionContext = ProviderBuiltInModelSuppressionContext;","entrypoint":"plugin-entry","exportName":"ProviderBuiltInModelSuppressionContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":516,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderBuiltInModelSuppressionResult = ProviderBuiltInModelSuppressionResult;","entrypoint":"plugin-entry","exportName":"ProviderBuiltInModelSuppressionResult","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":525,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderCacheTtlEligibilityContext = ProviderCacheTtlEligibilityContext;","entrypoint":"plugin-entry","exportName":"ProviderCacheTtlEligibilityContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":488,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderCatalogContext = ProviderCatalogContext;","entrypoint":"plugin-entry","exportName":"ProviderCatalogContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":255,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderCatalogResult = ProviderCatalogResult;","entrypoint":"plugin-entry","exportName":"ProviderCatalogResult","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":278,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderDefaultThinkingPolicyContext = ProviderDefaultThinkingPolicyContext;","entrypoint":"plugin-entry","exportName":"ProviderDefaultThinkingPolicyContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":549,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderDiscoveryContext = ProviderCatalogContext;","entrypoint":"plugin-entry","exportName":"ProviderDiscoveryContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":588,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderFetchUsageSnapshotContext = ProviderFetchUsageSnapshotContext;","entrypoint":"plugin-entry","exportName":"ProviderFetchUsageSnapshotContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":428,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderModernModelPolicyContext = ProviderModernModelPolicyContext;","entrypoint":"plugin-entry","exportName":"ProviderModernModelPolicyContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":559,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderNormalizeResolvedModelContext = ProviderNormalizeResolvedModelContext;","entrypoint":"plugin-entry","exportName":"ProviderNormalizeResolvedModelContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":339,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderPreparedRuntimeAuth = ProviderPreparedRuntimeAuth;","entrypoint":"plugin-entry","exportName":"ProviderPreparedRuntimeAuth","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":375,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderPrepareDynamicModelContext = ProviderResolveDynamicModelContext;","entrypoint":"plugin-entry","exportName":"ProviderPrepareDynamicModelContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":330,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderPrepareExtraParamsContext = ProviderPrepareExtraParamsContext;","entrypoint":"plugin-entry","exportName":"ProviderPrepareExtraParamsContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":461,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderPrepareRuntimeAuthContext = ProviderPrepareRuntimeAuthContext;","entrypoint":"plugin-entry","exportName":"ProviderPrepareRuntimeAuthContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":354,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderResolvedUsageAuth = ProviderResolvedUsageAuth;","entrypoint":"plugin-entry","exportName":"ProviderResolvedUsageAuth","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":415,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderResolveDynamicModelContext = ProviderResolveDynamicModelContext;","entrypoint":"plugin-entry","exportName":"ProviderResolveDynamicModelContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":313,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderResolveUsageAuthContext = ProviderResolveUsageAuthContext;","entrypoint":"plugin-entry","exportName":"ProviderResolveUsageAuthContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":396,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderRuntimeModel = ProviderRuntimeModel;","entrypoint":"plugin-entry","exportName":"ProviderRuntimeModel","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":296,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderThinkingPolicyContext = ProviderThinkingPolicyContext;","entrypoint":"plugin-entry","exportName":"ProviderThinkingPolicyContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":537,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type ProviderWrapStreamFnContext = ProviderWrapStreamFnContext;","entrypoint":"plugin-entry","exportName":"ProviderWrapStreamFnContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":478,"sourcePath":"src/plugins/types.ts"}
{"declaration":"export type SpeechProviderPlugin = SpeechProviderPlugin;","entrypoint":"plugin-entry","exportName":"SpeechProviderPlugin","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export","sourceLine":934,"sourcePath":"src/plugins/types.ts"}
{"category":"provider","entrypoint":"provider-onboard","importSpecifier":"openclaw/plugin-sdk/provider-onboard","recordType":"module","sourceLine":1,"sourcePath":"src/plugin-sdk/provider-onboard.ts"}
{"declaration":"export function applyAgentDefaultModelPrimary(cfg: OpenClawConfig, primary: string): OpenClawConfig;","entrypoint":"provider-onboard","exportName":"applyAgentDefaultModelPrimary","importSpecifier":"openclaw/plugin-sdk/provider-onboard","kind":"function","recordType":"export","sourceLine":76,"sourcePath":"src/plugins/provider-onboarding-config.ts"}
{"declaration":"export function applyCloudflareAiGatewayConfig(cfg: OpenClawConfig, params?: { accountId?: string | undefined; gatewayId?: string | undefined; } | undefined): OpenClawConfig;","entrypoint":"provider-onboard","exportName":"applyCloudflareAiGatewayConfig","importSpecifier":"openclaw/plugin-sdk/provider-onboard","kind":"function","recordType":"export","sourceLine":85,"sourcePath":"extensions/cloudflare-ai-gateway/onboard.ts"}

View File

@@ -48,6 +48,7 @@ function fakeApi(overrides: Partial<OpenClawPluginApi> = {}): OpenClawPluginApi
registerSpeechProvider() {},
registerMediaUnderstandingProvider() {},
registerImageGenerationProvider() {},
registerVideoGenerationProvider() {},
registerWebSearchProvider() {},
registerInteractiveHandler() {},
onConversationBindingResolved() {},

View File

@@ -541,6 +541,10 @@
"types": "./dist/plugin-sdk/twitch.d.ts",
"default": "./dist/plugin-sdk/twitch.js"
},
"./plugin-sdk/video-generation": {
"types": "./dist/plugin-sdk/video-generation.d.ts",
"default": "./dist/plugin-sdk/video-generation.js"
},
"./plugin-sdk/webhook-ingress": {
"types": "./dist/plugin-sdk/webhook-ingress.d.ts",
"default": "./dist/plugin-sdk/webhook-ingress.js"

View File

@@ -125,6 +125,7 @@
"tlon",
"tool-send",
"twitch",
"video-generation",
"webhook-ingress",
"webhook-path",
"web-media",

View File

@@ -26,6 +26,7 @@ import { createSessionsSpawnTool } from "./tools/sessions-spawn-tool.js";
import { createSessionsYieldTool } from "./tools/sessions-yield-tool.js";
import { createSubagentsTool } from "./tools/subagents-tool.js";
import { createTtsTool } from "./tools/tts-tool.js";
import { createVideoGenerateTool } from "./tools/video-generate-tool.js";
import { createWebFetchTool, createWebSearchTool } from "./tools/web-tools.js";
import { resolveWorkspaceRoot } from "./workspace-dir.js";
@@ -124,6 +125,10 @@ export function createOpenClawTools(
sandbox,
fsPolicy: options?.fsPolicy,
});
const videoGenerateTool = createVideoGenerateTool({
config: options?.config,
agentDir: options?.agentDir,
});
const pdfTool = options?.agentDir?.trim()
? createPdfTool({
config: options?.config,
@@ -186,6 +191,7 @@ export function createOpenClawTools(
config: options?.config,
}),
...(imageGenerateTool ? [imageGenerateTool] : []),
...(videoGenerateTool ? [videoGenerateTool] : []),
createGatewayTool({
agentSessionKey: options?.agentSessionKey,
config: options?.config,

View File

@@ -143,6 +143,7 @@ const TRUSTED_TOOL_RESULT_MEDIA = new Set([
"gateway",
"image",
"image_generate",
"video_generate",
"memory_get",
"memory_search",
"message",

View File

@@ -256,6 +256,7 @@ export function buildAgentSystemPrompt(params: {
"Show a /status-equivalent status card (usage + time + Reasoning/Verbose/Elevated); use for model-use questions (📊 session_status); optional per-session model override",
image: "Analyze an image with the configured image model",
image_generate: "Generate images with the configured image-generation model",
video_generate: "Generate short videos with the configured video-generation model",
};
const toolOrder = [
@@ -284,6 +285,7 @@ export function buildAgentSystemPrompt(params: {
"session_status",
"image",
"image_generate",
"video_generate",
];
const rawToolNames = (params.toolNames ?? []).map((tool) => tool.trim());

View File

@@ -241,6 +241,14 @@ const CORE_TOOL_DEFINITIONS: CoreToolDefinition[] = [
profiles: ["coding"],
includeInOpenClawGroup: true,
},
{
id: "video_generate",
label: "video_generate",
description: "Video generation",
sectionId: "media",
profiles: ["coding"],
includeInOpenClawGroup: true,
},
{
id: "tts",
label: "tts",

View File

@@ -142,6 +142,26 @@ export function readNumberParam(
return integer ? Math.trunc(value) : value;
}
export function readBooleanParam(
params: Record<string, unknown>,
key: string,
): boolean | undefined {
const raw = readParamRaw(params, key);
if (typeof raw === "boolean") {
return raw;
}
if (typeof raw === "string") {
const trimmed = raw.trim().toLowerCase();
if (trimmed === "true" || trimmed === "1") {
return true;
}
if (trimmed === "false" || trimmed === "0") {
return false;
}
}
return undefined;
}
export function readStringArrayParam(
params: Record<string, unknown>,
key: string,

View File

@@ -16,7 +16,7 @@ import { saveMediaBuffer } from "../../media/store.js";
import { loadWebMedia } from "../../media/web-media.js";
import { getProviderEnvVars } from "../../secrets/provider-env-vars.js";
import { resolveUserPath } from "../../utils.js";
import { ToolInputError, readNumberParam, readStringParam } from "./common.js";
import { ToolInputError, readBooleanParam, readNumberParam, readStringParam } from "./common.js";
import { decodeDataUrl } from "./image-tool.helpers.js";
import {
applyImageGenerationModelConfigDefaults,
@@ -106,6 +106,18 @@ const ImageGenerateToolSchema = Type.Object({
maximum: MAX_COUNT,
}),
),
seed: Type.Optional(Type.Number({ description: "Random seed for reproducibility." })),
watermark: Type.Optional(Type.Boolean({ description: "Add watermark to image." })),
guidanceScale: Type.Optional(
Type.Number({
description: "Controls prompt adherence strength (1.0-20.0). Higher means stricter.",
minimum: 1,
maximum: 20,
}),
),
optimizePrompt: Type.Optional(
Type.Boolean({ description: "Enable automatic prompt optimization for better results." }),
),
});
function getImageGenerationProviderAuthEnvVars(providerId: string): string[] {
@@ -579,6 +591,11 @@ export function createImageGenerateTool(options?: {
resolution,
});
const seed = readNumberParam(params, "seed", { integer: true });
const watermark = readBooleanParam(params, "watermark");
const guidanceScale = readNumberParam(params, "guidanceScale");
const optimizePrompt = readBooleanParam(params, "optimizePrompt");
const result = await generateImage({
cfg: effectiveCfg,
prompt,
@@ -589,6 +606,10 @@ export function createImageGenerateTool(options?: {
resolution,
count,
inputImages,
seed,
watermark,
guidanceScale,
optimizePrompt,
});
const savedImages = await Promise.all(

View File

@@ -0,0 +1,239 @@
import { Type } from "@sinclair/typebox";
import type { OpenClawConfig } from "../../config/config.js";
import { loadConfig } from "../../config/config.js";
import { saveMediaBuffer } from "../../media/store.js";
import {
generateVideo,
listRuntimeVideoGenerationProviders,
} from "../../video-generation/runtime.js";
import type { VideoGenerationProvider } from "../../video-generation/types.js";
import { ToolInputError, readBooleanParam, readNumberParam, readStringParam } from "./common.js";
import type { AnyAgentTool } from "./tool-runtime.helpers.js";
const SUPPORTED_ASPECT_RATIOS = new Set(["1:1", "3:4", "4:3", "9:16", "16:9", "21:9"]);
const VideoGenerateToolSchema = Type.Object({
action: Type.Optional(
Type.String({
description:
'Optional action: "generate" (default) or "list" to inspect available providers/models.',
}),
),
prompt: Type.Optional(Type.String({ description: "Video generation prompt." })),
model: Type.Optional(
Type.String({
description: "Optional provider/model override, e.g. byteplus/seedance-1-5-pro-251215.",
}),
),
duration: Type.Optional(
Type.Number({
description: "Duration in seconds (typically 4-12).",
minimum: 1,
maximum: 60,
}),
),
aspectRatio: Type.Optional(
Type.String({
description: "Optional aspect ratio: 1:1, 3:4, 4:3, 9:16, 16:9, or 21:9.",
}),
),
resolution: Type.Optional(
Type.String({
description: "Optional resolution: 480p, 720p, or 1080p.",
}),
),
seed: Type.Optional(Type.Number({ description: "Random seed for reproducibility." })),
watermark: Type.Optional(Type.Boolean({ description: "Add watermark to video." })),
firstFrameImageUrl: Type.Optional(
Type.String({
description: "URL of the first frame reference image for image-to-video (I2V) generation.",
}),
),
lastFrameImageUrl: Type.Optional(
Type.String({
description: "URL of the last frame reference image for I2V generation.",
}),
),
camerafixed: Type.Optional(
Type.Boolean({ description: "Fix camera position during generation." }),
),
draft: Type.Optional(
Type.Boolean({ description: "Draft mode for faster generation (forces 480p)." }),
),
});
function resolveAction(args: Record<string, unknown>): "generate" | "list" {
const raw = readStringParam(args, "action");
if (!raw) {
return "generate";
}
const normalized = raw.trim().toLowerCase();
if (normalized === "generate" || normalized === "list") {
return normalized;
}
throw new ToolInputError('action must be "generate" or "list"');
}
function buildListResponse(cfg?: OpenClawConfig): string {
const providers = listRuntimeVideoGenerationProviders({ config: cfg });
if (providers.length === 0) {
return "No video generation providers available. Install a plugin that supports video generation.";
}
const lines: string[] = ["Available video generation providers:"];
for (const provider of providers) {
const models = provider.models ?? (provider.defaultModel ? [provider.defaultModel] : []);
const capLines: string[] = [];
if (provider.capabilities.aspectRatios?.length) {
capLines.push(`aspect ratios: ${provider.capabilities.aspectRatios.join(", ")}`);
}
if (provider.capabilities.resolutions?.length) {
capLines.push(`resolutions: ${provider.capabilities.resolutions.join(", ")}`);
}
if (provider.capabilities.maxDurationSeconds) {
capLines.push(
`duration: ${provider.capabilities.minDurationSeconds ?? 1}-${provider.capabilities.maxDurationSeconds}s`,
);
}
lines.push(
`- ${provider.id}${provider.label ? ` (${provider.label})` : ""}: ${models.join(", ")}${capLines.length > 0 ? ` [${capLines.join("; ")}]` : ""}`,
);
}
return lines.join("\n");
}
function validateAspectRatio(
requested: string | undefined,
provider: VideoGenerationProvider | undefined,
): string | undefined {
if (!requested) {
return undefined;
}
const normalized = requested.trim();
if (!SUPPORTED_ASPECT_RATIOS.has(normalized)) {
throw new ToolInputError(
`Unsupported aspect ratio "${normalized}". Supported: ${[...SUPPORTED_ASPECT_RATIOS].join(", ")}`,
);
}
if (
provider?.capabilities.aspectRatios?.length &&
!provider.capabilities.aspectRatios.includes(normalized)
) {
throw new ToolInputError(
`Provider does not support aspect ratio "${normalized}". Supported: ${provider.capabilities.aspectRatios.join(", ")}`,
);
}
return normalized;
}
export function createVideoGenerateTool(params: {
config?: OpenClawConfig;
agentDir?: string;
}): AnyAgentTool | null {
const providers = listRuntimeVideoGenerationProviders({ config: params.config });
if (providers.length === 0) {
return null;
}
return {
label: "Video Generation",
name: "video_generate",
description:
'Generate a short video from a text prompt. Returns a saved video file path. Use action="list" to see available providers, models, and capabilities. Generated videos are delivered automatically from the tool result as MEDIA paths.',
parameters: VideoGenerateToolSchema,
execute: async (_toolCallId, args) => {
const rawArgs = args as Record<string, unknown>;
const cfg = params.config ?? loadConfig();
const action = resolveAction(rawArgs);
if (action === "list") {
return {
content: [{ type: "text", text: buildListResponse(cfg) }],
details: {},
};
}
const prompt = readStringParam(rawArgs, "prompt");
if (!prompt?.trim()) {
throw new ToolInputError("prompt is required for video generation");
}
const modelOverride = readStringParam(rawArgs, "model");
const duration = readNumberParam(rawArgs, "duration", { integer: true });
const aspectRatio = readStringParam(rawArgs, "aspectRatio");
const resolution = readStringParam(rawArgs, "resolution");
const seed = readNumberParam(rawArgs, "seed", { integer: true });
const watermark = readBooleanParam(rawArgs, "watermark");
const firstFrameImageUrl = readStringParam(rawArgs, "firstFrameImageUrl");
const lastFrameImageUrl = readStringParam(rawArgs, "lastFrameImageUrl");
const camerafixed = readBooleanParam(rawArgs, "camerafixed");
const draft = readBooleanParam(rawArgs, "draft");
const currentProviders = listRuntimeVideoGenerationProviders({ config: cfg });
const parsedOverride = modelOverride?.includes("/")
? { provider: modelOverride.split("/")[0] }
: null;
const validationProvider = parsedOverride
? (currentProviders.find((p) => p.id === parsedOverride.provider) ?? currentProviders[0])
: currentProviders[0];
const validatedAspectRatio = validateAspectRatio(aspectRatio, validationProvider);
const providerOptions: Record<string, unknown> = {};
if (camerafixed != null) {
providerOptions.camerafixed = camerafixed;
}
if (draft != null) {
providerOptions.draft = draft;
}
const result = await generateVideo({
cfg,
prompt: prompt.trim(),
agentDir: params.agentDir,
modelOverride,
durationSeconds: duration,
aspectRatio: validatedAspectRatio,
resolution: resolution?.trim(),
seed,
watermark,
firstFrameImageUrl,
lastFrameImageUrl,
providerOptions: Object.keys(providerOptions).length > 0 ? providerOptions : undefined,
});
const VIDEO_MAX_BYTES = 200 * 1024 * 1024; // 200MB for generated videos
const savedVideos = await Promise.all(
result.videos.map((video) =>
saveMediaBuffer(
video.buffer,
video.mimeType,
"tool-video-generation",
VIDEO_MAX_BYTES,
video.fileName,
),
),
);
const lines = [
`Generated ${savedVideos.length} video${savedVideos.length === 1 ? "" : "s"} with ${result.provider}/${result.model}.`,
];
return {
content: [{ type: "text", text: lines.join("\n") }],
details: {
provider: result.provider,
model: result.model,
count: savedVideos.length,
media: {
mediaUrls: savedVideos.map((video) => video.path),
},
paths: savedVideos.map((video) => video.path),
...(duration ? { duration } : {}),
...(validatedAspectRatio ? { aspectRatio: validatedAspectRatio } : {}),
...(resolution ? { resolution } : {}),
attempts: result.attempts,
metadata: result.metadata,
},
};
},
};
}

View File

@@ -102,6 +102,7 @@ const createRegistry = (channels: PluginRegistry["channels"]): PluginRegistry =>
speechProviders: [],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
gatewayHandlers: {},
httpRoutes: [],

View File

@@ -394,6 +394,7 @@ describe("ensureChannelSetupPluginInstalled", () => {
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: [],
gatewayMethods: [],
cliCommands: [],

View File

@@ -62,6 +62,7 @@ const createRegistry = (diagnostics: PluginDiagnostic[]): PluginRegistry => ({
speechProviders: [],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
gatewayHandlers: {},
httpRoutes: [],

View File

@@ -163,6 +163,7 @@ const createStubPluginRegistry = (): PluginRegistry => ({
],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
gatewayHandlers: {},
httpRoutes: [],

View File

@@ -30,6 +30,11 @@ export type GenerateImageParams = {
aspectRatio?: string;
resolution?: ImageGenerationResolution;
inputImages?: ImageGenerationSourceImage[];
seed?: number;
watermark?: boolean;
guidanceScale?: number;
optimizePrompt?: boolean;
providerOptions?: Record<string, unknown>;
};
export type GenerateImageRuntimeResult = {
@@ -153,6 +158,11 @@ export async function generateImage(
aspectRatio: params.aspectRatio,
resolution: params.resolution,
inputImages: params.inputImages,
seed: params.seed,
watermark: params.watermark,
guidanceScale: params.guidanceScale,
optimizePrompt: params.optimizePrompt,
providerOptions: params.providerOptions,
});
if (!Array.isArray(result.images) || result.images.length === 0) {
throw new Error("Image generation provider returned no images.");

View File

@@ -31,6 +31,12 @@ export type ImageGenerationRequest = {
aspectRatio?: string;
resolution?: ImageGenerationResolution;
inputImages?: ImageGenerationSourceImage[];
seed?: number;
watermark?: boolean;
guidanceScale?: number;
optimizePrompt?: boolean;
/** Provider-specific options (e.g. sequential generation). */
providerOptions?: Record<string, unknown>;
};
export type ImageGenerationResult = {

View File

@@ -0,0 +1,10 @@
// Public video-generation helpers and types for provider plugins.
export type {
GeneratedVideoAsset,
VideoGenerationProvider,
VideoGenerationProviderCapabilities,
VideoGenerationRequest,
VideoGenerationResult,
VideoGenerationSourceImage,
} from "../video-generation/types.js";

View File

@@ -5,6 +5,7 @@ import type {
OpenClawPluginApi,
ProviderPlugin,
SpeechProviderPlugin,
VideoGenerationProviderPlugin,
WebSearchProviderPlugin,
} from "./types.js";
@@ -14,6 +15,7 @@ export type CapturedPluginRegistration = {
speechProviders: SpeechProviderPlugin[];
mediaUnderstandingProviders: MediaUnderstandingProviderPlugin[];
imageGenerationProviders: ImageGenerationProviderPlugin[];
videoGenerationProviders: VideoGenerationProviderPlugin[];
webSearchProviders: WebSearchProviderPlugin[];
tools: AnyAgentTool[];
};
@@ -23,6 +25,7 @@ export function createCapturedPluginRegistration(): CapturedPluginRegistration {
const speechProviders: SpeechProviderPlugin[] = [];
const mediaUnderstandingProviders: MediaUnderstandingProviderPlugin[] = [];
const imageGenerationProviders: ImageGenerationProviderPlugin[] = [];
const videoGenerationProviders: VideoGenerationProviderPlugin[] = [];
const webSearchProviders: WebSearchProviderPlugin[] = [];
const tools: AnyAgentTool[] = [];
@@ -31,6 +34,7 @@ export function createCapturedPluginRegistration(): CapturedPluginRegistration {
speechProviders,
mediaUnderstandingProviders,
imageGenerationProviders,
videoGenerationProviders,
webSearchProviders,
tools,
api: {
@@ -46,6 +50,9 @@ export function createCapturedPluginRegistration(): CapturedPluginRegistration {
registerImageGenerationProvider(provider: ImageGenerationProviderPlugin) {
imageGenerationProviders.push(provider);
},
registerVideoGenerationProvider(provider: VideoGenerationProviderPlugin) {
videoGenerationProviders.push(provider);
},
registerWebSearchProvider(provider: WebSearchProviderPlugin) {
webSearchProviders.push(provider);
},

View File

@@ -182,6 +182,7 @@ describe("plugin contract registry", () => {
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: ["exa"],
toolNames: [],
});
@@ -190,6 +191,7 @@ describe("plugin contract registry", () => {
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: ["firecrawl"],
toolNames: ["firecrawl_search", "firecrawl_scrape"],
});
@@ -198,6 +200,7 @@ describe("plugin contract registry", () => {
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: ["tavily"],
toolNames: ["tavily_search", "tavily_extract"],
});
@@ -209,6 +212,7 @@ describe("plugin contract registry", () => {
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: ["fal"],
videoGenerationProviderIds: [],
webSearchProviderIds: [],
});
expect(findRegistrationForPlugin("google")).toMatchObject({
@@ -216,6 +220,7 @@ describe("plugin contract registry", () => {
speechProviderIds: [],
mediaUnderstandingProviderIds: ["google"],
imageGenerationProviderIds: ["google"],
videoGenerationProviderIds: [],
webSearchProviderIds: ["gemini"],
});
expect(findRegistrationForPlugin("openai")).toMatchObject({
@@ -223,18 +228,21 @@ describe("plugin contract registry", () => {
speechProviderIds: ["openai"],
mediaUnderstandingProviderIds: ["openai"],
imageGenerationProviderIds: ["openai"],
videoGenerationProviderIds: [],
});
expect(findRegistrationForPlugin("elevenlabs")).toMatchObject({
providerIds: [],
speechProviderIds: ["elevenlabs"],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
});
expect(findRegistrationForPlugin("microsoft")).toMatchObject({
providerIds: [],
speechProviderIds: ["microsoft"],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
});
});

View File

@@ -75,6 +75,7 @@ type PluginRegistrationContractEntry = {
speechProviderIds: string[];
mediaUnderstandingProviderIds: string[];
imageGenerationProviderIds: string[];
videoGenerationProviderIds: string[];
webSearchProviderIds: string[];
toolNames: string[];
};
@@ -419,6 +420,10 @@ function upsertPluginRegistrationContractEntry(
existing.imageGenerationProviderIds,
next.imageGenerationProviderIds,
);
existing.videoGenerationProviderIds = mergeIds(
existing.videoGenerationProviderIds,
next.videoGenerationProviderIds,
);
existing.webSearchProviderIds = mergeIds(
existing.webSearchProviderIds,
next.webSearchProviderIds,
@@ -443,6 +448,7 @@ function mergeProviderContractRegistrations(
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: [],
toolNames: [],
});
@@ -464,6 +470,9 @@ function loadPluginRegistrationContractRegistry(): PluginRegistrationContractEnt
imageGenerationProviderIds: captured.imageGenerationProviders.map(
(provider) => provider.id,
),
videoGenerationProviderIds: captured.videoGenerationProviders.map(
(provider) => provider.id,
),
webSearchProviderIds: captured.webSearchProviders.map((provider) => provider.id),
toolNames: captured.tools.map((tool) => tool.name),
});

View File

@@ -20,6 +20,7 @@ function createPluginRecord(id: string, name: string): PluginRecord {
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: [],
gatewayMethods: [],
cliCommands: [],

View File

@@ -20,6 +20,7 @@ export function createMockPluginRegistry(
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: [],
gatewayMethods: [],
cliCommands: [],
@@ -45,6 +46,7 @@ export function createMockPluginRegistry(
speechProviders: [],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
httpRoutes: [],
gatewayHandlers: {},

View File

@@ -351,6 +351,7 @@ function createPluginRecord(params: {
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: [],
gatewayMethods: [],
cliCommands: [],

View File

@@ -12,6 +12,7 @@ export function createEmptyPluginRegistry(): PluginRegistry {
speechProviders: [],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
gatewayHandlers: {},
httpRoutes: [],

View File

@@ -26,6 +26,7 @@ import {
} from "./types.js";
import type {
ImageGenerationProviderPlugin,
VideoGenerationProviderPlugin,
OpenClawPluginApi,
OpenClawPluginChannelRegistration,
OpenClawPluginCliRegistrar,
@@ -123,6 +124,8 @@ export type PluginMediaUnderstandingProviderRegistration =
PluginOwnedProviderRegistration<MediaUnderstandingProviderPlugin>;
export type PluginImageGenerationProviderRegistration =
PluginOwnedProviderRegistration<ImageGenerationProviderPlugin>;
export type PluginVideoGenerationProviderRegistration =
PluginOwnedProviderRegistration<VideoGenerationProviderPlugin>;
export type PluginWebSearchProviderRegistration =
PluginOwnedProviderRegistration<WebSearchProviderPlugin>;
@@ -182,6 +185,7 @@ export type PluginRecord = {
speechProviderIds: string[];
mediaUnderstandingProviderIds: string[];
imageGenerationProviderIds: string[];
videoGenerationProviderIds: string[];
webSearchProviderIds: string[];
gatewayMethods: string[];
cliCommands: string[];
@@ -205,6 +209,7 @@ export type PluginRegistry = {
speechProviders: PluginSpeechProviderRegistration[];
mediaUnderstandingProviders: PluginMediaUnderstandingProviderRegistration[];
imageGenerationProviders: PluginImageGenerationProviderRegistration[];
videoGenerationProviders: PluginVideoGenerationProviderRegistration[];
webSearchProviders: PluginWebSearchProviderRegistration[];
gatewayHandlers: GatewayRequestHandlers;
httpRoutes: PluginHttpRouteRegistration[];
@@ -644,6 +649,19 @@ export function createPluginRegistry(registryParams: PluginRegistryParams) {
});
};
const registerVideoGenerationProvider = (
record: PluginRecord,
provider: VideoGenerationProviderPlugin,
) => {
registerUniqueProviderLike({
record,
provider,
kindLabel: "video-generation provider",
registrations: registry.videoGenerationProviders,
ownedIds: record.videoGenerationProviderIds,
});
};
const registerWebSearchProvider = (record: PluginRecord, provider: WebSearchProviderPlugin) => {
registerUniqueProviderLike({
record,
@@ -918,6 +936,10 @@ export function createPluginRegistry(registryParams: PluginRegistryParams) {
registrationMode === "full"
? (provider) => registerImageGenerationProvider(record, provider)
: () => {},
registerVideoGenerationProvider:
registrationMode === "full"
? (provider) => registerVideoGenerationProvider(record, provider)
: () => {},
registerWebSearchProvider:
registrationMode === "full"
? (provider) => registerWebSearchProvider(record, provider)

View File

@@ -47,6 +47,7 @@ export function createPluginRecord(
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: [],
gatewayMethods: [],
cliCommands: [],
@@ -110,6 +111,7 @@ export function createPluginLoadResult(
speechProviders: [],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
tools: [],
hooks: [],

View File

@@ -1,13 +1,4 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import {
createCompatibilityNotice,
createCustomHook,
createPluginLoadResult,
createPluginRecord,
createTypedHook,
HOOK_ONLY_MESSAGE,
LEGACY_BEFORE_AGENT_START_MESSAGE,
} from "./status.test-helpers.js";
const loadConfigMock = vi.fn();
const loadOpenClawPluginsMock = vi.fn();
@@ -36,22 +27,32 @@ vi.mock("../agents/workspace.js", () => ({
resolveDefaultAgentWorkspaceDir: () => "/default-workspace",
}));
function setPluginLoadResult(overrides: Partial<ReturnType<typeof createPluginLoadResult>>) {
loadOpenClawPluginsMock.mockReturnValue(
createPluginLoadResult({
plugins: [],
...overrides,
}),
);
}
describe("buildPluginStatusReport", () => {
beforeEach(async () => {
vi.resetModules();
loadConfigMock.mockReset();
loadOpenClawPluginsMock.mockReset();
loadConfigMock.mockReturnValue({});
setPluginLoadResult({ plugins: [] });
loadOpenClawPluginsMock.mockReturnValue({
plugins: [],
diagnostics: [],
channels: [],
providers: [],
speechProviders: [],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
tools: [],
hooks: [],
typedHooks: [],
channelSetups: [],
httpRoutes: [],
gatewayHandlers: {},
cliRegistrars: [],
services: [],
commands: [],
});
({
buildAllPluginInspectReports,
buildPluginCompatibilityNotices,
@@ -82,17 +83,52 @@ describe("buildPluginStatusReport", () => {
});
it("normalizes bundled plugin versions to the core base release", () => {
setPluginLoadResult({
loadOpenClawPluginsMock.mockReturnValue({
plugins: [
createPluginRecord({
{
id: "whatsapp",
name: "WhatsApp",
description: "Bundled channel plugin",
version: "2026.3.22",
source: "/tmp/whatsapp/index.ts",
origin: "bundled",
enabled: true,
status: "loaded",
toolNames: [],
hookNames: [],
channelIds: ["whatsapp"],
}),
providerIds: [],
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: [],
gatewayMethods: [],
cliCommands: [],
services: [],
commands: [],
httpRoutes: 0,
hookCount: 0,
configSchema: false,
},
],
diagnostics: [],
channels: [],
providers: [],
speechProviders: [],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
tools: [],
hooks: [],
typedHooks: [],
channelSetups: [],
httpRoutes: [],
gatewayHandlers: {},
cliRegistrars: [],
services: [],
commands: [],
});
const report = buildPluginStatusReport({
@@ -119,21 +155,58 @@ describe("buildPluginStatusReport", () => {
},
},
});
setPluginLoadResult({
loadOpenClawPluginsMock.mockReturnValue({
plugins: [
createPluginRecord({
{
id: "google",
name: "Google",
description: "Google provider plugin",
source: "/tmp/google/index.ts",
origin: "bundled",
enabled: true,
status: "loaded",
toolNames: [],
hookNames: [],
channelIds: [],
providerIds: ["google"],
speechProviderIds: [],
mediaUnderstandingProviderIds: ["google"],
imageGenerationProviderIds: ["google"],
videoGenerationProviderIds: [],
webSearchProviderIds: ["google"],
}),
gatewayMethods: [],
cliCommands: [],
services: [],
commands: [],
httpRoutes: 0,
hookCount: 0,
configSchema: false,
},
],
diagnostics: [{ level: "warn", pluginId: "google", message: "watch this surface" }],
typedHooks: [createTypedHook({ pluginId: "google", hookName: "before_agent_start" })],
channels: [],
channelSetups: [],
providers: [],
speechProviders: [],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
tools: [],
hooks: [],
typedHooks: [
{
pluginId: "google",
hookName: "before_agent_start",
handler: () => undefined,
source: "/tmp/google/index.ts",
},
],
httpRoutes: [],
gatewayHandlers: {},
cliRegistrars: [],
services: [],
commands: [],
});
const inspect = buildPluginInspectReport({ id: "google" });
@@ -149,7 +222,13 @@ describe("buildPluginStatusReport", () => {
]);
expect(inspect?.usesLegacyBeforeAgentStart).toBe(true);
expect(inspect?.compatibility).toEqual([
createCompatibilityNotice({ pluginId: "google", code: "legacy-before-agent-start" }),
{
pluginId: "google",
code: "legacy-before-agent-start",
severity: "warn",
message:
"still uses legacy before_agent_start; keep regression coverage on this plugin, and prefer before_model_resolve/before_prompt_build for new work.",
},
]);
expect(inspect?.policy).toEqual({
allowPromptInjection: false,
@@ -163,25 +242,94 @@ describe("buildPluginStatusReport", () => {
});
it("builds inspect reports for every loaded plugin", () => {
setPluginLoadResult({
loadOpenClawPluginsMock.mockReturnValue({
plugins: [
createPluginRecord({
{
id: "lca",
name: "LCA",
description: "Legacy hook plugin",
source: "/tmp/lca/index.ts",
origin: "workspace",
enabled: true,
status: "loaded",
toolNames: [],
hookNames: [],
channelIds: [],
providerIds: [],
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: [],
gatewayMethods: [],
cliCommands: [],
services: [],
commands: [],
httpRoutes: 0,
hookCount: 1,
}),
createPluginRecord({
configSchema: false,
},
{
id: "microsoft",
name: "Microsoft",
description: "Hybrid capability plugin",
source: "/tmp/microsoft/index.ts",
origin: "bundled",
enabled: true,
status: "loaded",
toolNames: [],
hookNames: [],
channelIds: [],
providerIds: ["microsoft"],
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: ["microsoft"],
}),
gatewayMethods: [],
cliCommands: [],
services: [],
commands: [],
httpRoutes: 0,
hookCount: 0,
configSchema: false,
},
],
hooks: [createCustomHook({ pluginId: "lca", events: ["message"] })],
typedHooks: [createTypedHook({ pluginId: "lca", hookName: "before_agent_start" })],
diagnostics: [],
channels: [],
channelSetups: [],
providers: [],
speechProviders: [],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
tools: [],
hooks: [
{
pluginId: "lca",
events: ["message"],
entry: {
hook: {
name: "legacy",
handler: () => undefined,
},
},
},
],
typedHooks: [
{
pluginId: "lca",
hookName: "before_agent_start",
handler: () => undefined,
source: "/tmp/lca/index.ts",
},
],
httpRoutes: [],
gatewayHandlers: {},
cliRegistrars: [],
services: [],
commands: [],
});
const inspect = buildAllPluginInspectReports();
@@ -196,58 +344,221 @@ describe("buildPluginStatusReport", () => {
});
it("builds compatibility warnings for legacy compatibility paths", () => {
setPluginLoadResult({
loadOpenClawPluginsMock.mockReturnValue({
plugins: [
createPluginRecord({
{
id: "lca",
name: "LCA",
description: "Legacy hook plugin",
source: "/tmp/lca/index.ts",
origin: "workspace",
enabled: true,
status: "loaded",
toolNames: [],
hookNames: [],
channelIds: [],
providerIds: [],
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: [],
gatewayMethods: [],
cliCommands: [],
services: [],
commands: [],
httpRoutes: 0,
hookCount: 1,
}),
configSchema: false,
},
],
typedHooks: [createTypedHook({ pluginId: "lca", hookName: "before_agent_start" })],
diagnostics: [],
channels: [],
channelSetups: [],
providers: [],
speechProviders: [],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
tools: [],
hooks: [],
typedHooks: [
{
pluginId: "lca",
hookName: "before_agent_start",
handler: () => undefined,
source: "/tmp/lca/index.ts",
},
],
httpRoutes: [],
gatewayHandlers: {},
cliRegistrars: [],
services: [],
commands: [],
});
expect(buildPluginCompatibilityWarnings()).toEqual([
`lca ${LEGACY_BEFORE_AGENT_START_MESSAGE}`,
`lca ${HOOK_ONLY_MESSAGE}`,
"lca still uses legacy before_agent_start; keep regression coverage on this plugin, and prefer before_model_resolve/before_prompt_build for new work.",
"lca is hook-only. This remains a supported compatibility path, but it has not migrated to explicit capability registration yet.",
]);
});
it("builds structured compatibility notices with deterministic ordering", () => {
setPluginLoadResult({
loadOpenClawPluginsMock.mockReturnValue({
plugins: [
createPluginRecord({
{
id: "hook-only",
name: "Hook Only",
description: "",
source: "/tmp/hook-only/index.ts",
origin: "workspace",
enabled: true,
status: "loaded",
toolNames: [],
hookNames: [],
channelIds: [],
providerIds: [],
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: [],
gatewayMethods: [],
cliCommands: [],
services: [],
commands: [],
httpRoutes: 0,
hookCount: 1,
}),
createPluginRecord({
configSchema: false,
},
{
id: "legacy-only",
name: "Legacy Only",
description: "",
source: "/tmp/legacy-only/index.ts",
origin: "workspace",
enabled: true,
status: "loaded",
toolNames: [],
hookNames: [],
channelIds: [],
providerIds: ["legacy-only"],
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: [],
gatewayMethods: [],
cliCommands: [],
services: [],
commands: [],
httpRoutes: 0,
hookCount: 1,
}),
configSchema: false,
},
],
hooks: [createCustomHook({ pluginId: "hook-only", events: ["message"] })],
typedHooks: [createTypedHook({ pluginId: "legacy-only", hookName: "before_agent_start" })],
diagnostics: [],
channels: [],
channelSetups: [],
providers: [],
speechProviders: [],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
tools: [],
hooks: [
{
pluginId: "hook-only",
events: ["message"],
entry: {
hook: {
name: "legacy",
handler: () => undefined,
},
},
},
],
typedHooks: [
{
pluginId: "legacy-only",
hookName: "before_agent_start",
handler: () => undefined,
source: "/tmp/legacy-only/index.ts",
},
],
httpRoutes: [],
gatewayHandlers: {},
cliRegistrars: [],
services: [],
commands: [],
});
expect(buildPluginCompatibilityNotices()).toEqual([
createCompatibilityNotice({ pluginId: "hook-only", code: "hook-only" }),
createCompatibilityNotice({ pluginId: "legacy-only", code: "legacy-before-agent-start" }),
{
pluginId: "hook-only",
code: "hook-only",
severity: "info",
message:
"is hook-only. This remains a supported compatibility path, but it has not migrated to explicit capability registration yet.",
},
{
pluginId: "legacy-only",
code: "legacy-before-agent-start",
severity: "warn",
message:
"still uses legacy before_agent_start; keep regression coverage on this plugin, and prefer before_model_resolve/before_prompt_build for new work.",
},
]);
});
it("returns no compatibility warnings for modern capability plugins", () => {
setPluginLoadResult({
loadOpenClawPluginsMock.mockReturnValue({
plugins: [
createPluginRecord({
{
id: "modern",
name: "Modern",
description: "",
source: "/tmp/modern/index.ts",
origin: "workspace",
enabled: true,
status: "loaded",
toolNames: [],
hookNames: [],
channelIds: [],
providerIds: ["modern"],
}),
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: [],
gatewayMethods: [],
cliCommands: [],
services: [],
commands: [],
httpRoutes: 0,
hookCount: 0,
configSchema: false,
},
],
diagnostics: [],
channels: [],
channelSetups: [],
providers: [],
speechProviders: [],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
tools: [],
hooks: [],
typedHooks: [],
httpRoutes: [],
gatewayHandlers: {},
cliRegistrars: [],
services: [],
commands: [],
});
expect(buildPluginCompatibilityNotices()).toEqual([]);
@@ -255,19 +566,55 @@ describe("buildPluginStatusReport", () => {
});
it("populates bundleCapabilities from plugin record", () => {
setPluginLoadResult({
loadOpenClawPluginsMock.mockReturnValue({
plugins: [
createPluginRecord({
{
id: "claude-bundle",
name: "Claude Bundle",
description: "A bundle plugin with skills and commands",
source: "/tmp/claude-bundle/.claude-plugin/plugin.json",
origin: "workspace",
enabled: true,
status: "loaded",
format: "bundle",
bundleFormat: "claude",
bundleCapabilities: ["skills", "commands", "agents", "settings"],
rootDir: "/tmp/claude-bundle",
}),
toolNames: [],
hookNames: [],
channelIds: [],
providerIds: [],
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: [],
gatewayMethods: [],
cliCommands: [],
services: [],
commands: [],
httpRoutes: 0,
hookCount: 0,
configSchema: false,
},
],
diagnostics: [],
channels: [],
channelSetups: [],
providers: [],
speechProviders: [],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
tools: [],
hooks: [],
typedHooks: [],
httpRoutes: [],
gatewayHandlers: {},
cliRegistrars: [],
services: [],
commands: [],
});
const inspect = buildPluginInspectReport({ id: "claude-bundle" });
@@ -279,15 +626,51 @@ describe("buildPluginStatusReport", () => {
});
it("returns empty bundleCapabilities and mcpServers for non-bundle plugins", () => {
setPluginLoadResult({
loadOpenClawPluginsMock.mockReturnValue({
plugins: [
createPluginRecord({
{
id: "plain-plugin",
name: "Plain Plugin",
description: "A regular plugin",
source: "/tmp/plain-plugin/index.ts",
origin: "workspace",
enabled: true,
status: "loaded",
toolNames: [],
hookNames: [],
channelIds: [],
providerIds: ["plain"],
}),
speechProviderIds: [],
mediaUnderstandingProviderIds: [],
imageGenerationProviderIds: [],
videoGenerationProviderIds: [],
webSearchProviderIds: [],
gatewayMethods: [],
cliCommands: [],
services: [],
commands: [],
httpRoutes: 0,
hookCount: 0,
configSchema: false,
},
],
diagnostics: [],
channels: [],
channelSetups: [],
providers: [],
speechProviders: [],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
tools: [],
hooks: [],
typedHooks: [],
httpRoutes: [],
gatewayHandlers: {},
cliRegistrars: [],
services: [],
commands: [],
});
const inspect = buildPluginInspectReport({ id: "plain-plugin" });
@@ -298,18 +681,27 @@ describe("buildPluginStatusReport", () => {
});
it("formats and summarizes compatibility notices", () => {
const notice = createCompatibilityNotice({
const notice = {
pluginId: "legacy-plugin",
code: "legacy-before-agent-start",
});
code: "legacy-before-agent-start" as const,
severity: "warn" as const,
message:
"still uses legacy before_agent_start; keep regression coverage on this plugin, and prefer before_model_resolve/before_prompt_build for new work.",
};
expect(formatPluginCompatibilityNotice(notice)).toBe(
`legacy-plugin ${LEGACY_BEFORE_AGENT_START_MESSAGE}`,
"legacy-plugin still uses legacy before_agent_start; keep regression coverage on this plugin, and prefer before_model_resolve/before_prompt_build for new work.",
);
expect(
summarizePluginCompatibility([
notice,
createCompatibilityNotice({ pluginId: "legacy-plugin", code: "hook-only" }),
{
pluginId: "legacy-plugin",
code: "hook-only",
severity: "info",
message:
"is hook-only. This remains a supported compatibility path, but it has not migrated to explicit capability registration yet.",
},
]),
).toEqual({
noticeCount: 2,

View File

@@ -21,6 +21,7 @@ export type PluginCapabilityKind =
| "speech"
| "media-understanding"
| "image-generation"
| "video-generation"
| "web-search"
| "channel";
@@ -165,6 +166,7 @@ function buildCapabilityEntries(plugin: PluginRegistry["plugins"][number]) {
{ kind: "speech" as const, ids: plugin.speechProviderIds },
{ kind: "media-understanding" as const, ids: plugin.mediaUnderstandingProviderIds },
{ kind: "image-generation" as const, ids: plugin.imageGenerationProviderIds },
{ kind: "video-generation" as const, ids: plugin.videoGenerationProviderIds },
{ kind: "web-search" as const, ids: plugin.webSearchProviderIds },
{ kind: "channel" as const, ids: plugin.channelIds },
].filter((entry) => entry.ids.length > 0);

View File

@@ -40,6 +40,7 @@ import type {
SpeechTelephonySynthesisResult,
SpeechVoiceOption,
} from "../tts/provider-types.js";
import type { VideoGenerationProvider } from "../video-generation/types.js";
import type { WizardPrompter } from "../wizard/prompts.js";
import type { SecretInputMode } from "./provider-auth-types.js";
import type { createVpsAwareOAuthHandlers } from "./provider-oauth-flow.js";
@@ -950,6 +951,7 @@ export type PluginSpeechProviderEntry = SpeechProviderPlugin & {
export type MediaUnderstandingProviderPlugin = MediaUnderstandingProvider;
export type ImageGenerationProviderPlugin = ImageGenerationProvider;
export type VideoGenerationProviderPlugin = VideoGenerationProvider;
export type OpenClawPluginGatewayMethod = {
method: string;
@@ -1352,6 +1354,8 @@ export type OpenClawPluginApi = {
registerMediaUnderstandingProvider: (provider: MediaUnderstandingProviderPlugin) => void;
/** Register an image generation provider (image generation capability). */
registerImageGenerationProvider: (provider: ImageGenerationProviderPlugin) => void;
/** Register a video generation provider (video generation capability). */
registerVideoGenerationProvider: (provider: VideoGenerationProviderPlugin) => void;
/** Register a web search provider (web search capability). */
registerWebSearchProvider: (provider: WebSearchProviderPlugin) => void;
registerInteractiveHandler: (registration: PluginInteractiveHandlerRegistration) => void;

View File

@@ -29,6 +29,7 @@ export const createTestRegistry = (channels: TestChannelRegistration[] = []): Pl
speechProviders: [],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
gatewayHandlers: {},
httpRoutes: [],

View File

@@ -0,0 +1,80 @@
import { normalizeProviderId } from "../agents/model-selection.js";
import type { OpenClawConfig } from "../config/config.js";
import { isBlockedObjectKey } from "../infra/prototype-keys.js";
import { loadOpenClawPlugins } from "../plugins/loader.js";
import { getActivePluginRegistry, getActivePluginRegistryKey } from "../plugins/runtime.js";
import type { VideoGenerationProviderPlugin } from "../plugins/types.js";
const BUILTIN_VIDEO_GENERATION_PROVIDERS: readonly VideoGenerationProviderPlugin[] = [];
const UNSAFE_PROVIDER_IDS = new Set(["__proto__", "constructor", "prototype"]);
function normalizeVideoGenerationProviderId(id: string | undefined): string | undefined {
const normalized = normalizeProviderId(id ?? "");
if (!normalized || isBlockedObjectKey(normalized)) {
return undefined;
}
return normalized;
}
function isSafeVideoGenerationProviderId(id: string | undefined): id is string {
return Boolean(id && !UNSAFE_PROVIDER_IDS.has(id));
}
function resolvePluginVideoGenerationProviders(
cfg?: OpenClawConfig,
): VideoGenerationProviderPlugin[] {
const active = getActivePluginRegistry();
const registry =
(active?.videoGenerationProviders?.length ?? 0) > 0 || getActivePluginRegistryKey() || !cfg
? active
: loadOpenClawPlugins({ config: cfg });
return registry?.videoGenerationProviders?.map((entry) => entry.provider) ?? [];
}
function buildProviderMaps(cfg?: OpenClawConfig): {
canonical: Map<string, VideoGenerationProviderPlugin>;
aliases: Map<string, VideoGenerationProviderPlugin>;
} {
const canonical = new Map<string, VideoGenerationProviderPlugin>();
const aliases = new Map<string, VideoGenerationProviderPlugin>();
const register = (provider: VideoGenerationProviderPlugin) => {
const id = normalizeVideoGenerationProviderId(provider.id);
if (!isSafeVideoGenerationProviderId(id)) {
return;
}
canonical.set(id, provider);
aliases.set(id, provider);
for (const alias of provider.aliases ?? []) {
const normalizedAlias = normalizeVideoGenerationProviderId(alias);
if (isSafeVideoGenerationProviderId(normalizedAlias)) {
aliases.set(normalizedAlias, provider);
}
}
};
for (const provider of BUILTIN_VIDEO_GENERATION_PROVIDERS) {
register(provider);
}
for (const provider of resolvePluginVideoGenerationProviders(cfg)) {
register(provider);
}
return { canonical, aliases };
}
export function listVideoGenerationProviders(
cfg?: OpenClawConfig,
): VideoGenerationProviderPlugin[] {
return [...buildProviderMaps(cfg).canonical.values()];
}
export function getVideoGenerationProvider(
providerId: string | undefined,
cfg?: OpenClawConfig,
): VideoGenerationProviderPlugin | undefined {
const normalized = normalizeVideoGenerationProviderId(providerId);
if (!normalized) {
return undefined;
}
return buildProviderMaps(cfg).aliases.get(normalized);
}

View File

@@ -0,0 +1,179 @@
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import { describeFailoverError, isFailoverError } from "../agents/failover-error.js";
import type { FallbackAttempt } from "../agents/model-fallback.types.js";
import type { OpenClawConfig } from "../config/config.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import { getVideoGenerationProvider, listVideoGenerationProviders } from "./provider-registry.js";
import type { GeneratedVideoAsset, VideoGenerationResult } from "./types.js";
const log = createSubsystemLogger("video-generation");
export type GenerateVideoParams = {
cfg: OpenClawConfig;
prompt: string;
agentDir?: string;
authStore?: AuthProfileStore;
modelOverride?: string;
durationSeconds?: number;
aspectRatio?: string;
resolution?: string;
seed?: number;
watermark?: boolean;
firstFrameImageUrl?: string;
lastFrameImageUrl?: string;
providerOptions?: Record<string, unknown>;
};
export type GenerateVideoRuntimeResult = {
videos: GeneratedVideoAsset[];
provider: string;
model: string;
attempts: FallbackAttempt[];
metadata?: Record<string, unknown>;
};
function parseModelRef(raw: string | undefined): { provider: string; model: string } | null {
const trimmed = raw?.trim();
if (!trimmed) {
return null;
}
const slashIndex = trimmed.indexOf("/");
if (slashIndex <= 0 || slashIndex === trimmed.length - 1) {
return null;
}
return {
provider: trimmed.slice(0, slashIndex).trim(),
model: trimmed.slice(slashIndex + 1).trim(),
};
}
function resolveVideoGenerationCandidates(params: {
cfg: OpenClawConfig;
modelOverride?: string;
}): Array<{ provider: string; model: string }> {
const candidates: Array<{ provider: string; model: string }> = [];
const seen = new Set<string>();
const add = (raw: string | undefined) => {
const parsed = parseModelRef(raw);
if (!parsed) {
return;
}
const key = `${parsed.provider}/${parsed.model}`;
if (seen.has(key)) {
return;
}
seen.add(key);
candidates.push(parsed);
};
add(params.modelOverride);
// Fall back to first registered provider's default model
if (candidates.length === 0) {
const providers = listVideoGenerationProviders(params.cfg);
for (const provider of providers) {
if (provider.defaultModel) {
add(`${provider.id}/${provider.defaultModel}`);
break;
}
}
}
return candidates;
}
function throwVideoGenerationFailure(params: {
attempts: FallbackAttempt[];
lastError: unknown;
}): never {
if (params.attempts.length <= 1 && params.lastError) {
throw params.lastError;
}
const summary =
params.attempts.length > 0
? params.attempts
.map((attempt) => `${attempt.provider}/${attempt.model}: ${attempt.error}`)
.join(" | ")
: "unknown";
throw new Error(`All video generation models failed (${params.attempts.length}): ${summary}`, {
cause: params.lastError instanceof Error ? params.lastError : undefined,
});
}
export function listRuntimeVideoGenerationProviders(params?: { config?: OpenClawConfig }) {
return listVideoGenerationProviders(params?.config);
}
export async function generateVideo(
params: GenerateVideoParams,
): Promise<GenerateVideoRuntimeResult> {
const candidates = resolveVideoGenerationCandidates({
cfg: params.cfg,
modelOverride: params.modelOverride,
});
if (candidates.length === 0) {
throw new Error(
"No video-generation model configured. Install a provider plugin that supports video generation (e.g. @openclaw/byteplus-provider).",
);
}
const attempts: FallbackAttempt[] = [];
let lastError: unknown;
for (const candidate of candidates) {
const provider = getVideoGenerationProvider(candidate.provider, params.cfg);
if (!provider) {
const error = `No video-generation provider registered for ${candidate.provider}`;
attempts.push({ provider: candidate.provider, model: candidate.model, error });
lastError = new Error(error);
continue;
}
try {
const result: VideoGenerationResult = await provider.generateVideo({
provider: candidate.provider,
model: candidate.model,
prompt: params.prompt,
cfg: params.cfg,
agentDir: params.agentDir,
authStore: params.authStore,
durationSeconds: params.durationSeconds,
aspectRatio: params.aspectRatio,
resolution: params.resolution,
seed: params.seed,
watermark: params.watermark,
firstFrameImage: params.firstFrameImageUrl
? { url: params.firstFrameImageUrl, role: "first_frame" }
: undefined,
lastFrameImage: params.lastFrameImageUrl
? { url: params.lastFrameImageUrl, role: "last_frame" }
: undefined,
providerOptions: params.providerOptions,
});
if (!Array.isArray(result.videos) || result.videos.length === 0) {
throw new Error("Video generation provider returned no videos.");
}
return {
videos: result.videos,
provider: candidate.provider,
model: result.model ?? candidate.model,
attempts,
metadata: result.metadata,
};
} catch (err) {
lastError = err;
const described = isFailoverError(err) ? describeFailoverError(err) : undefined;
attempts.push({
provider: candidate.provider,
model: candidate.model,
error: described?.message ?? (err instanceof Error ? err.message : String(err)),
reason: described?.reason,
status: described?.status,
code: described?.code,
});
log.debug(`video-generation candidate failed: ${candidate.provider}/${candidate.model}`);
}
}
throwVideoGenerationFailure({ attempts, lastError });
}

View File

@@ -0,0 +1,62 @@
import type { AuthProfileStore } from "../agents/auth-profiles.js";
import type { OpenClawConfig } from "../config/config.js";
export type GeneratedVideoAsset = {
buffer: Buffer;
mimeType: string;
fileName?: string;
durationSeconds?: number;
metadata?: Record<string, unknown>;
};
export type VideoGenerationSourceImage = {
url?: string;
buffer?: Buffer;
mimeType?: string;
role: "first_frame" | "last_frame";
};
export type VideoGenerationRequest = {
provider: string;
model: string;
prompt: string;
cfg: OpenClawConfig;
agentDir?: string;
authStore?: AuthProfileStore;
timeoutMs?: number;
durationSeconds?: number;
aspectRatio?: string;
resolution?: string;
seed?: number;
watermark?: boolean;
firstFrameImage?: VideoGenerationSourceImage;
lastFrameImage?: VideoGenerationSourceImage;
/** Provider-specific options (e.g. camerafixed, draft). */
providerOptions?: Record<string, unknown>;
};
export type VideoGenerationResult = {
videos: GeneratedVideoAsset[];
model?: string;
metadata?: Record<string, unknown>;
};
export type VideoGenerationProviderCapabilities = {
supportsDuration?: boolean;
supportsAspectRatio?: boolean;
supportsResolution?: boolean;
maxDurationSeconds?: number;
minDurationSeconds?: number;
aspectRatios?: string[];
resolutions?: string[];
};
export type VideoGenerationProvider = {
id: string;
aliases?: string[];
label?: string;
defaultModel?: string;
models?: string[];
capabilities: VideoGenerationProviderCapabilities;
generateVideo: (req: VideoGenerationRequest) => Promise<VideoGenerationResult>;
};

View File

@@ -18,6 +18,7 @@ export function createTestPluginApi(api: TestPluginApiInput): OpenClawPluginApi
registerSpeechProvider() {},
registerMediaUnderstandingProvider() {},
registerImageGenerationProvider() {},
registerVideoGenerationProvider() {},
registerWebSearchProvider() {},
registerInteractiveHandler() {},
onConversationBindingResolved() {},

View File

@@ -59,7 +59,6 @@ import type { OpenClawConfig } from "../src/config/config.js";
import type { OutboundSendDeps } from "../src/infra/outbound/deliver.js";
import { installProcessWarningFilter } from "../src/infra/warning-filter.js";
import type { PluginRegistry } from "../src/plugins/registry.js";
import { createTestRegistry } from "../src/test-utils/channel-plugins.js";
import { cleanupSessionStateForTest } from "../src/test-utils/session-state-cleanup.js";
import { withIsolatedTestHome } from "./test-env.js";
@@ -78,6 +77,12 @@ type RegistryState = {
version: number;
};
type TestChannelRegistration = {
pluginId: string;
plugin: unknown;
source: string;
};
const globalRegistryState = (() => {
const globalState = globalThis as typeof globalThis & {
[REGISTRY_STATE]?: RegistryState;
@@ -219,6 +224,33 @@ const createStubPlugin = (params: {
outbound: createStubOutbound(params.id, params.deliveryMode),
});
const createTestRegistry = (channels: TestChannelRegistration[] = []): PluginRegistry => ({
plugins: [],
tools: [],
hooks: [],
typedHooks: [],
channels: channels as unknown as PluginRegistry["channels"],
channelSetups: channels.map((entry) => ({
pluginId: entry.pluginId,
plugin: entry.plugin as PluginRegistry["channelSetups"][number]["plugin"],
source: entry.source,
enabled: true,
})),
providers: [],
speechProviders: [],
mediaUnderstandingProviders: [],
imageGenerationProviders: [],
videoGenerationProviders: [],
webSearchProviders: [],
gatewayHandlers: {},
httpRoutes: [],
cliRegistrars: [],
services: [],
commands: [],
conversationBindingResolvedHandlers: [],
diagnostics: [],
});
const createDefaultRegistry = () =>
createTestRegistry([
{