feat: add update_effect tool for modifying existing effect params
This commit is contained in:
parent
277321628c
commit
9775f6f30c
|
|
@ -617,6 +617,66 @@ export const EditorContextAdapter = {
|
|||
appliedParams: element.params,
|
||||
};
|
||||
},
|
||||
|
||||
updateEffectElement({
|
||||
elementId,
|
||||
params,
|
||||
}: {
|
||||
elementId: string;
|
||||
params: Record<string, number | string | boolean>;
|
||||
}):
|
||||
| {
|
||||
success: boolean;
|
||||
elementId: string;
|
||||
appliedParams: Record<string, number | string | boolean>;
|
||||
}
|
||||
| { error: string } {
|
||||
const core = EditorCore.getInstance();
|
||||
const activeScene = core.scenes.getActiveSceneOrNull();
|
||||
if (!activeScene) {
|
||||
return { error: "No active timeline" };
|
||||
}
|
||||
|
||||
const [resolved] = findTimelineElementsWithTracksByIds({
|
||||
tracks: activeScene.tracks,
|
||||
elementIds: [elementId],
|
||||
});
|
||||
if (!resolved) {
|
||||
return { error: `Timeline element not found: ${elementId}` };
|
||||
}
|
||||
if (resolved.element.type !== "effect") {
|
||||
return { error: "Element is not an effect" };
|
||||
}
|
||||
|
||||
const effectElement = resolved.element as import("@/lib/timeline/types").EffectElement;
|
||||
const definition = effectsRegistry.get(effectElement.effectType);
|
||||
if (!definition) {
|
||||
return { error: `Effect not found: ${effectElement.effectType}` };
|
||||
}
|
||||
|
||||
const validationError = validateEffectParams(definition.params, params);
|
||||
if (validationError) {
|
||||
return { error: validationError };
|
||||
}
|
||||
|
||||
const mergedParams = { ...effectElement.params, ...params };
|
||||
|
||||
core.timeline.updateElements({
|
||||
updates: [
|
||||
{
|
||||
trackId: resolved.track.id,
|
||||
elementId,
|
||||
patch: { params: mergedParams } as Partial<import("@/lib/timeline/types").TimelineElement>,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
elementId,
|
||||
appliedParams: mergedParams,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
function secondsToTicks(seconds: number): number {
|
||||
|
|
|
|||
|
|
@ -23,3 +23,4 @@ import "@/agent/tools/update-text.tool";
|
|||
import "@/agent/tools/list-effects.tool";
|
||||
import "@/agent/tools/get-effect.tool";
|
||||
import "@/agent/tools/apply-effect.tool";
|
||||
import "@/agent/tools/update-effect.tool";
|
||||
|
|
|
|||
|
|
@ -161,6 +161,16 @@ export const applyEffectSchema: ToolSchema = {
|
|||
],
|
||||
};
|
||||
|
||||
export const updateEffectSchema: ToolSchema = {
|
||||
name: "update_effect",
|
||||
description:
|
||||
"Updates parameters of an existing effect element on the timeline. Use list_timeline to find the elementId of the effect, then pass the params you want to change. Only the provided parameters are updated; others keep their current values. Use get_effect to discover valid parameter keys and ranges.",
|
||||
parameters: [
|
||||
{ key: "elementId", type: "string", required: true },
|
||||
{ key: "params", type: "object", required: true },
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* The exact list of schemas exposed to the LLM.
|
||||
* Excludes internal-only tools (transcribe_video, mock).
|
||||
|
|
@ -179,4 +189,5 @@ export const providerToolSchemas: ToolSchema[] = [
|
|||
listEffectsSchema,
|
||||
getEffectSchema,
|
||||
applyEffectSchema,
|
||||
updateEffectSchema,
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
import type { AgentContext, ToolDefinition } from "@/agent/types";
|
||||
import { toolRegistry } from "@/agent/tools/registry";
|
||||
import { updateEffectSchema } from "@/agent/tools/schemas";
|
||||
import { EditorContextAdapter } from "@/agent/context";
|
||||
|
||||
const updateEffectTool: ToolDefinition = {
|
||||
...updateEffectSchema,
|
||||
execute: async (
|
||||
args: Record<string, unknown>,
|
||||
_context: AgentContext,
|
||||
): Promise<
|
||||
| {
|
||||
success: boolean;
|
||||
elementId: string;
|
||||
appliedParams: Record<string, number | string | boolean>;
|
||||
}
|
||||
| { error: string }
|
||||
> => {
|
||||
const elementId = args.elementId;
|
||||
const params = args.params as
|
||||
| Record<string, number | string | boolean>
|
||||
| undefined;
|
||||
|
||||
if (typeof elementId !== "string" || !elementId.trim()) {
|
||||
return { error: "Invalid element id" };
|
||||
}
|
||||
|
||||
if (!params || typeof params !== "object" || Object.keys(params).length === 0) {
|
||||
return { error: "params is required and must be a non-empty object" };
|
||||
}
|
||||
|
||||
return EditorContextAdapter.updateEffectElement({
|
||||
elementId,
|
||||
params,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
toolRegistry.register(updateEffectSchema.name, updateEffectTool);
|
||||
|
|
@ -654,6 +654,49 @@ Agregar un efecto como elemento standalone al timeline en una pista de efectos,
|
|||
|
||||
---
|
||||
|
||||
## 17. `update_effect`
|
||||
|
||||
### Propósito
|
||||
Actualizar los parámetros de un elemento de efecto existente en el timeline. Solo se actualizan los parámetros proporcionados; el resto mantiene sus valores actuales.
|
||||
|
||||
### Input
|
||||
```ts
|
||||
{
|
||||
elementId: string;
|
||||
params: Record<string, number | string | boolean>;
|
||||
}
|
||||
```
|
||||
|
||||
### Output
|
||||
```ts
|
||||
{
|
||||
success: boolean;
|
||||
elementId: string;
|
||||
appliedParams: Record<string, number | string | boolean>;
|
||||
}
|
||||
```
|
||||
|
||||
### Requirements
|
||||
- MUST validate `elementId` exists in the active timeline.
|
||||
- MUST validate the target element is an effect element (`type: "effect"`).
|
||||
- MUST validate `params` against the effect's parameter definitions (types, ranges).
|
||||
- MUST merge provided `params` with existing params (only override specified keys).
|
||||
- MUST use `updateElements` to apply the param patch.
|
||||
- MUST preserve undo/redo behavior.
|
||||
- MUST return the full merged params after update.
|
||||
|
||||
### Errors
|
||||
- Invalid element id: `{ error: "Invalid element id" }`.
|
||||
- Missing params: `{ error: "params is required and must be a non-empty object" }`.
|
||||
- No active timeline: `{ error: "No active timeline" }`.
|
||||
- Missing element: `{ error: "Timeline element not found: <id>" }`.
|
||||
- Wrong type: `{ error: "Element is not an effect" }`.
|
||||
- Effect not found: `{ error: "Effect not found: <type>" }`.
|
||||
- Unknown parameter: `{ error: "Unknown parameter: <key>" }`.
|
||||
- Out of range: `{ error: "Parameter '<key>' must be >= <min>" }`.
|
||||
|
||||
---
|
||||
|
||||
## Existing/secondary tool: `transcribe_video`
|
||||
|
||||
### Propósito
|
||||
|
|
|
|||
Loading…
Reference in New Issue