create_cue_sequence
Generate a sequence of lighting cues by combining existing scenes, specifying transitions, and defining script context for the LacyLights system to enhance theatrical lighting design.
Instructions
Create a sequence of lighting cues from existing scenes
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project ID to create cue sequence in | |
| sceneIds | Yes | Scene IDs to include in sequence | |
| scriptContext | Yes | Script context for the cue sequence | |
| sequenceName | Yes | Name for the cue sequence | |
| transitionPreferences | No |
Input Schema (JSON Schema)
{
"properties": {
"projectId": {
"description": "Project ID to create cue sequence in",
"type": "string"
},
"sceneIds": {
"description": "Scene IDs to include in sequence",
"items": {
"type": "string"
},
"type": "array"
},
"scriptContext": {
"description": "Script context for the cue sequence",
"type": "string"
},
"sequenceName": {
"description": "Name for the cue sequence",
"type": "string"
},
"transitionPreferences": {
"properties": {
"autoAdvance": {
"default": false,
"type": "boolean"
},
"defaultFadeIn": {
"default": 3,
"type": "number"
},
"defaultFadeOut": {
"default": 3,
"type": "number"
},
"followCues": {
"default": false,
"type": "boolean"
}
},
"type": "object"
}
},
"required": [
"projectId",
"scriptContext",
"sceneIds",
"sequenceName"
],
"type": "object"
}
Implementation Reference
- src/tools/cue-tools.ts:159-279 (handler)Main handler implementation for create_cue_sequence tool. Parses input, validates scenes, generates cue timing using AI service, creates cue list and individual cues in database, returns detailed results with statistics.async createCueSequence(args: z.infer<typeof CreateCueSequenceSchema>) { const { projectId, scriptContext, sceneIds, sequenceName, transitionPreferences, } = CreateCueSequenceSchema.parse(args); try { // Get project and validate scenes const project = await this.graphqlClient.getProject(projectId); if (!project) { throw new Error(`Project with ID ${projectId} not found`); } // Map scenes in the exact order of sceneIds to maintain consistency const scenes = sceneIds.map((sceneId) => { const scene = project.scenes.find((s) => s.id === sceneId); if (!scene) { throw new Error(`Scene with ID ${sceneId} not found in the project`); } return scene; }); // Convert scenes to GeneratedScene format for AI processing const generatedScenes: GeneratedScene[] = scenes.map((scene) => ({ name: scene.name, description: scene.description || "", fixtureValues: scene.fixtureValues.map((fv) => ({ fixtureId: fv.fixture.id, channelValues: fv.channelValues, // Already a number array })), reasoning: `Existing scene: ${scene.name}`, })); // Generate cue sequence using AI const cueSequence = await this.aiLightingService.generateCueSequence( scriptContext, generatedScenes, transitionPreferences, ); // Create the cue list in the database const cueList = await this.graphqlClient.createCueList({ name: sequenceName, description: cueSequence.description, projectId, }); // Create individual cues const createdCues = []; for (let i = 0; i < cueSequence.cues.length; i++) { const cueData = cueSequence.cues[i]; // The AI returns sceneId as a string that might be an index or scene reference // Try to parse it as an index first let sceneId: string; const sceneIdAsNumber = parseInt(cueData.sceneId); if ( !isNaN(sceneIdAsNumber) && sceneIdAsNumber >= 0 && sceneIdAsNumber < sceneIds.length ) { // It's a valid index, use it sceneId = sceneIds[sceneIdAsNumber]; } else { // Try to find it in the sceneIds array const sceneIndex = sceneIds.findIndex((id) => id === cueData.sceneId); sceneId = sceneIndex >= 0 ? sceneIds[sceneIndex] : sceneIds[Math.min(i, sceneIds.length - 1)]; // Fallback to corresponding index or last scene } const cue = await this.graphqlClient.createCue({ name: cueData.name, cueNumber: cueData.cueNumber, cueListId: cueList.id, sceneId: sceneId, fadeInTime: cueData.fadeInTime, fadeOutTime: cueData.fadeOutTime, followTime: cueData.followTime, notes: cueData.notes, }); createdCues.push(cue); } return { cueListId: cueList.id, cueList: { name: cueList.name, description: cueList.description, totalCues: createdCues.length, }, cues: createdCues.map((cue) => ({ id: cue.id, name: cue.name, cueNumber: cue.cueNumber, fadeInTime: cue.fadeInTime, fadeOutTime: cue.fadeOutTime, followTime: cue.followTime, notes: cue.notes, sceneName: cue.scene.name, })), sequenceReasoning: cueSequence.reasoning, statistics: { totalCues: createdCues.length, averageFadeTime: createdCues.reduce((sum, cue) => sum + cue.fadeInTime, 0) / createdCues.length, followCues: createdCues.filter((cue) => cue.followTime !== null) .length, estimatedDuration: this.estimateSequenceDuration(createdCues), }, }; } catch (error) { throw new Error(`Failed to create cue sequence: ${error}`); } }
- src/tools/cue-tools.ts:23-36 (schema)Zod schema for validating input parameters to the create_cue_sequence tool.const CreateCueSequenceSchema = z.object({ projectId: z.string(), scriptContext: z.string(), sceneIds: z.array(z.string()), sequenceName: z.string(), transitionPreferences: z .object({ defaultFadeIn: z.number().default(3), defaultFadeOut: z.number().default(3), followCues: z.boolean().default(false), autoAdvance: z.boolean().default(false), }) .optional(), });
- src/index.ts:1182-1222 (registration)Tool registration in listTools handler: defines name, description, and inputSchema advertised to MCP clients.name: "create_cue_sequence", description: "Create a sequence of lighting cues from existing scenes", inputSchema: { type: "object", properties: { projectId: { type: "string", description: "Project ID to create cue sequence in", }, scriptContext: { type: "string", description: "Script context for the cue sequence", }, sceneIds: { type: "array", items: { type: "string" }, description: "Scene IDs to include in sequence", }, sequenceName: { type: "string", description: "Name for the cue sequence", }, transitionPreferences: { type: "object", properties: { defaultFadeIn: { type: "number", default: 3 }, defaultFadeOut: { type: "number", default: 3 }, followCues: { type: "boolean", default: false }, autoAdvance: { type: "boolean", default: false }, }, }, }, required: [ "projectId", "scriptContext", "sceneIds", "sequenceName", ], }, },
- src/index.ts:2254-2266 (registration)Tool call handler dispatch: routes create_cue_sequence calls to cueTools.createCueSequence method.case "create_cue_sequence": return { content: [ { type: "text", text: JSON.stringify( await this.cueTools.createCueSequence(args as any), null, 2, ), }, ], };
- src/index.ts:57-61 (registration)Instantiation of CueTools class instance used for handling cue-related tools including create_cue_sequence.this.cueTools = new CueTools( this.graphqlClient, this.ragService, this.aiLightingService, );