neverminedio/movie-script-generator-agent
A TypeScript-based agent that generates detailed technical scripts for music videos using LangChain + OpenAI, integrated with the Nevermined Payments API for orchestrating multi-step tasks and managing subscriptions or billing.
The Music Video Technical Script Generator Agent automates the process of creating complex, production-ready scripts for music videos. Drawing on AI-powered text generation, the agent:
All steps are event-driven, with tasks managed and billed through Nevermined. By subscribing to step-updated
events, this agent listens for instructions and updates each step’s status as it progresses (e.g., from Pending
to Completed
).
This Movie Script Generator Agent is part of a larger ecosystem of AI-driven media creation. For a complete view of how multiple agents work together, see:
Image / Video Generator Agent
Workflow Example:
[ User Prompt ] --> [Music Orchestrator] --> [Song Generation] --> [Script Generation] --> [Image/Video Generation] --> [Final Compilation]
step-updated
events, updates the workflow’s steps, and logs progress remotely.AGENT_DID
)Clone this repository:
git clone https://github.com/nevermined-io/music-video-script-generator-agent.git
cd music-video-script-generator-agent
Install dependencies:
npm install
Build the project (optional for production):
npm run build
Rename .env.example
to .env
and set the required keys:
NVM_API_KEY=your_nevermined_api_key
NVM_ENVIRONMENT=testing
AGENT_DID=did:nv:your_agent_did
OPENAI_API_KEY=your_openai_api_key
IS_DUMMY=false
NVM_API_KEY
and NVM_ENVIRONMENT
configure the connection to Nevermined.AGENT_DID
sets the unique identifier for this agent.OPENAI_API_KEY
grants access to OpenAI’s text generation models.IS_DUMMY
controls whether to use a “dummy” mode (returning static data instead of calling real services).music-video-script-generator-agent/
├── main.ts # Main entry (initializes Payments, subscribes to steps)
├── config/
│ └── env.ts # Environment configuration
├── steps/
│ └── stepHandlers.ts # Core logic for handling each step
├── sceneTechnicalExtractor.ts # Class for script creation, scene extraction, etc.
├── types.ts # Shared TypeScript interfaces (e.g., Scene)
├── logger/
│ └── logger.ts # Logging system (local + remote)
├── .env.example # Environment template
├── package.json
├── tsconfig.json
└── README.md # This file
main.ts
: Handles task lifecycle, from receiving steps to sending back results.sceneTechnicalExtractor.ts
: Implements the multi-step logic for generating the initial script, extracting scenes, identifying settings, and extracting characters.stepHandlers.ts
: Coordinates the different steps (init
, generateScript
, extractScenes
, generateSettings
, extractCharacters
, and transformScenes
) that shape the final output.logger/logger.ts
: A logging system that logs both locally and through the Nevermined Payments API.Initialization (init
step)
init
.generateScript
, extractScenes
, generateSettings
, extractCharacters
, transformScenes
).Script Generation (generateScript
)
Scene Extraction (extractScenes
)
Settings Generation (generateSettings
)
Characters Extraction (extractCharacters
)
Scene Transformation (transformScenes
)
Throughout these steps, the agent updates each step’s status (from Pending
to Completed
or Failed
) in the Nevermined system. If a step fails, it logs the error and halts.
After installing and configuring .env
:
npm start
NVM_API_KEY
and listens for step-updated
events for AGENT_DID
.The Music Video Technical Script Generator leverages LangChain and OpenAI to create production-ready scripts with precise technical specs—scene-by-scene breakdowns, camera movements, lighting setups, color palettes, lens/stabilizer recommendations, visual references, transitions, and more. All of this is integrated with Nevermined's Payments API for structured task handling and billing.
npm install
, configure .env
).npm run build
.npm start
. The agent will connect to Nevermined and await new tasks.music-video-script-generator-agent/
├── src/
│ ├── main.ts # Agent entry point for step subscription
│ ├── steps/
│ │ └── stepHandlers.ts # Detailed step logic (init, generateScript, etc.)
│ ├── sceneTechnicalExtractor.ts # Core logic for generating / extracting script data
│ ├── logger/
│ │ └── logger.ts # Logging system
│ └── config/
│ └── env.ts # Environment variable load
├── .env.example # Environment template
├── package.json # Dependencies
├── tsconfig.json # TypeScript config
└── README.md
Notable Files
sceneTechnicalExtractor.ts
: Contains the logic to generate an initial script (via OpenAI), then parse out scenes, settings, and characters, returning structured JSON data.stepHandlers.ts
: Defines the workflow steps, updating the task in the Nevermined system accordingly.Below is a step-by-step outline of how Nevermined orchestrates tasks in this agent:
Initialize the Payments Instance
import { Payments, EnvironmentName } from "@nevermined-io/payments";
const payments = Payments.getInstance({
nvmApiKey: process.env.NVM_API_KEY!,
environment: process.env.NVM_ENVIRONMENT as EnvironmentName,
});
if (!payments.isLoggedIn) {
throw new Error("Failed to authenticate with Nevermined.");
}
This connects to Nevermined using the API key and environment.
Subscribe to Task Updates
await payments.query.subscribe(run, {
joinAccountRoom: false,
joinAgentRooms: [process.env.AGENT_DID!],
subscribeEventTypes: ["step-updated"],
getPendingEventsOnSubscribe: false,
});
Here, run
is a callback that processes each step-updated
event.
Task Lifecycle
payments.query.getStep(stepId)
.payments.query.updateStep(step.did, { ... })
.In main.ts
, you’ll typically see:
await payments.query.subscribe(processSteps(payments), {
joinAccountRoom: false,
joinAgentRooms: [AGENT_DID],
subscribeEventTypes: ["step-updated"],
getPendingEventsOnSubscribe: false,
});
processSteps(payments)
is invoked with the event data.In stepHandlers.ts
, you might see something like:
export function processSteps(payments: Payments) {
return async (data: any) => {
const eventData = JSON.parse(data);
const step = await payments.query.getStep(eventData.step_id);
if (step.name === "init") {
// create sub-steps (generateScript, extractScenes, etc.)
} else if (step.name === "generateScript") {
// call handleScriptGeneration() ...
}
// ...
};
}
The agent checks the step’s name and dispatches it to the right logic (e.g., generateScript
, extractScenes
). Each step runs an AI-driven process or data extraction, then updates the step status accordingly.
LangChain manages prompts and output parsers. For example, in sceneTechnicalExtractor.ts
, we might see:
import { ChatOpenAI } from "@langchain/openai";
import { ChatPromptTemplate } from "@langchain/core/prompts";
export class SceneTechnicalExtractor {
private scriptChain = /* Sequence definition with ChatOpenAI... */
async generateScript({ idea, title, lyrics, tags, duration }) {
// builds a prompt with specialized instructions
return await this.scriptChain.invoke({ idea, title, lyrics, tags, duration });
}
}
This approach instructs the AI to produce a screenplay-like text with scenes, durations, camera specs, etc.
To record events:
import { logMessage } from "../logger/logger";
logMessage(payments, {
task_id: step.task_id,
level: "info",
message: `Processing step: ${step.name}`,
});
This logs both locally and in Nevermined, ensuring a full audit trail for each sub-step.
Development Server
npm run dev
Build
npm run build
Testing
npm test
Apache License 2.0
(C) 2025 Nevermined AG
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
docker pull neverminedio/movie-script-generator-agent