diff --git a/CHANGELOG.md b/CHANGELOG.md index 4654f4fe034..eab4056f29c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -159,6 +159,7 @@ Docs: https://docs.openclaw.ai ### Fixes +- Agents/tools: keep image, video, and music generation tool registration on manifest/auth control-plane checks instead of loading runtime provider registries during reply startup, reducing live-path tool-prep blocking while leaving provider runtime resolution for execution and list actions. Thanks @shakkernerd. - fix: block workspace CLOUDSDK_PYTHON override and always set trusted interpreter for gcloud. (#74492) Thanks @pgondhi987. - Providers/Z.AI: move the bundled GLM catalog and auth env metadata into the plugin manifest, so `models list --all --provider zai` shows the full known catalog without duplicated runtime seed data. Thanks @shakkernerd. - Providers/Qianfan and Providers/Stepfun: declare setup auth metadata (`api-key` method, `QIANFAN_API_KEY`, `STEPFUN_API_KEY`) in the plugin manifest so onboarding and `models setup` surface the expected env var without falling back to legacy `providerAuthEnvVars` runtime seed data. Thanks @shakkernerd. diff --git a/src/agents/tools/image-generate-tool.test.ts b/src/agents/tools/image-generate-tool.test.ts index 8d527ea334a..c665cc9505a 100644 --- a/src/agents/tools/image-generate-tool.test.ts +++ b/src/agents/tools/image-generate-tool.test.ts @@ -248,6 +248,29 @@ describe("createImageGenerateTool", () => { expect(JSON.stringify(tool.parameters)).toContain("openai/gpt-image-1.5"); }); + it("does not load runtime providers while registering an explicitly configured tool", () => { + const listProviders = vi + .spyOn(imageGenerationRuntime, "listRuntimeImageGenerationProviders") + .mockImplementation(() => { + throw new Error("runtime provider list should not run during tool registration"); + }); + + expect( + createImageGenerateTool({ + config: { + agents: { + defaults: { + imageGenerationModel: { + primary: "openai/gpt-image-1", + }, + }, + }, + }, + }), + ).not.toBeNull(); + expect(listProviders).not.toHaveBeenCalled(); + }); + it("matches image-generation providers across canonical provider aliases", () => { vi.spyOn(imageGenerationRuntime, "listRuntimeImageGenerationProviders").mockReturnValue([ { diff --git a/src/agents/tools/image-generate-tool.ts b/src/agents/tools/image-generate-tool.ts index a6a9afccb66..d4d552c5742 100644 --- a/src/agents/tools/image-generate-tool.ts +++ b/src/agents/tools/image-generate-tool.ts @@ -573,7 +573,6 @@ export function createImageGenerateTool(options?: { cfg, agentDir: options?.agentDir, modelConfig: cfg.agents?.defaults?.imageGenerationModel, - providers: () => listRuntimeImageGenerationProviders({ config: cfg }), providerKey: "imageGenerationProviders", }) ) { diff --git a/src/agents/tools/music-generate-tool.test.ts b/src/agents/tools/music-generate-tool.test.ts index d5142676dd7..a70d0c1fcb4 100644 --- a/src/agents/tools/music-generate-tool.test.ts +++ b/src/agents/tools/music-generate-tool.test.ts @@ -148,6 +148,27 @@ describe("createMusicGenerateTool", () => { ).not.toBeNull(); }); + it("does not load runtime providers while registering an explicitly configured tool", () => { + const listProviders = vi + .spyOn(musicGenerationRuntime, "listRuntimeMusicGenerationProviders") + .mockImplementation(() => { + throw new Error("runtime provider list should not run during tool registration"); + }); + + expect( + createMusicGenerateTool({ + config: asConfig({ + agents: { + defaults: { + musicGenerationModel: { primary: "google/lyria-3-clip-preview" }, + }, + }, + }), + }), + ).not.toBeNull(); + expect(listProviders).not.toHaveBeenCalled(); + }); + it("generates tracks, saves them, and emits MEDIA paths without a session-backed detach", async () => { taskExecutorMocks.createRunningTaskRun.mockReturnValue({ taskId: "task-123", diff --git a/src/agents/tools/music-generate-tool.ts b/src/agents/tools/music-generate-tool.ts index f187d5fe3b1..603f90f250e 100644 --- a/src/agents/tools/music-generate-tool.ts +++ b/src/agents/tools/music-generate-tool.ts @@ -501,7 +501,6 @@ export function createMusicGenerateTool(options?: { cfg, agentDir: options?.agentDir, modelConfig: cfg.agents?.defaults?.musicGenerationModel, - providers: () => listRuntimeMusicGenerationProviders({ config: cfg }), providerKey: "musicGenerationProviders", }) ) { diff --git a/src/agents/tools/video-generate-tool.test.ts b/src/agents/tools/video-generate-tool.test.ts index 74512be2c7d..9465d73bd67 100644 --- a/src/agents/tools/video-generate-tool.test.ts +++ b/src/agents/tools/video-generate-tool.test.ts @@ -113,6 +113,27 @@ describe("createVideoGenerateTool", () => { ).not.toBeNull(); }); + it("does not load runtime providers while registering an explicitly configured tool", () => { + const listProviders = vi + .spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders") + .mockImplementation(() => { + throw new Error("runtime provider list should not run during tool registration"); + }); + + expect( + createVideoGenerateTool({ + config: asConfig({ + agents: { + defaults: { + videoGenerationModel: { primary: "qwen/wan2.6-t2v" }, + }, + }, + }), + }), + ).not.toBeNull(); + expect(listProviders).not.toHaveBeenCalled(); + }); + it("orders auto-detected provider defaults by canonical aliases", () => { vi.spyOn(videoGenerationRuntime, "listRuntimeVideoGenerationProviders").mockReturnValue([ { diff --git a/src/agents/tools/video-generate-tool.ts b/src/agents/tools/video-generate-tool.ts index 3ba6dd4f390..f59f8558d8e 100644 --- a/src/agents/tools/video-generate-tool.ts +++ b/src/agents/tools/video-generate-tool.ts @@ -808,7 +808,6 @@ export function createVideoGenerateTool(options?: { cfg, agentDir: options?.agentDir, modelConfig: cfg.agents?.defaults?.videoGenerationModel, - providers: () => listRuntimeVideoGenerationProviders({ config: cfg }), providerKey: "videoGenerationProviders", }) ) {