-
Notifications
You must be signed in to change notification settings - Fork 40
Expand file tree
/
Copy path41_sequential_pipeline_tools.py
More file actions
218 lines (179 loc) · 6.52 KB
/
Copy path41_sequential_pipeline_tools.py
File metadata and controls
218 lines (179 loc) · 6.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# Copyright (c) 2025 Agentspan
# Licensed under the MIT License. See LICENSE file in the project root for details.
"""Sequential Pipeline with Stage-Level Tools — movie production pipeline.
Demonstrates the sequential strategy where EACH sub-agent in the pipeline
has its own tools for producing structured output. Each stage builds on
the previous one's output:
concept_developer → scriptwriter → visual_director → audio_designer → producer
This shows how to give individual pipeline agents their own tools while
composing them into an ordered sequence using the >> operator.
Requirements:
- Conductor server with LLM support
- AGENTSPAN_SERVER_URL=http://localhost:8080/api as environment variable
- AGENTSPAN_LLM_MODEL=openai/gpt-4o-mini as environment variable
"""
from conductor.ai.agents import Agent, AgentRuntime, tool
from settings import settings
# ── Stage tools ──────────────────────────────────────────────────────
@tool
def create_concept(title: str, genre: str, logline: str) -> dict:
"""Create a movie concept document.
Args:
title: Working title for the short film.
genre: Genre (e.g., sci-fi, drama, comedy).
logline: One-sentence summary of the story.
Returns:
Dictionary with the structured concept.
"""
return {
"concept": {
"title": title,
"genre": genre,
"logline": logline,
"status": "approved",
}
}
@tool
def write_scene(scene_number: int, location: str, action: str,
dialogue: str = "") -> dict:
"""Write a single scene for the script.
Args:
scene_number: Scene number in sequence.
location: Scene location description.
action: Action/direction description.
dialogue: Optional dialogue for the scene.
Returns:
Dictionary with the formatted scene.
"""
scene = {
"scene": scene_number,
"location": location,
"action": action,
}
if dialogue:
scene["dialogue"] = dialogue
return {"scene": scene}
@tool
def describe_visual(scene_number: int, shot_type: str,
description: str) -> dict:
"""Describe visual direction for a scene.
Args:
scene_number: Which scene this visual is for.
shot_type: Camera shot type (wide, close-up, tracking, etc.).
description: Visual description including lighting, color, mood.
Returns:
Dictionary with the visual direction.
"""
return {
"visual": {
"scene": scene_number,
"shot_type": shot_type,
"description": description,
}
}
@tool
def specify_audio(scene_number: int, music_mood: str,
sound_effects: str) -> dict:
"""Specify audio direction for a scene.
Args:
scene_number: Which scene this audio is for.
music_mood: Music mood/style description.
sound_effects: Key sound effects needed.
Returns:
Dictionary with the audio specification.
"""
return {
"audio": {
"scene": scene_number,
"music_mood": music_mood,
"sound_effects": sound_effects,
}
}
@tool
def assemble_production(title: str, total_scenes: int,
estimated_runtime: str) -> dict:
"""Assemble final production notes.
Args:
title: Final title of the short film.
total_scenes: Number of scenes in the final cut.
estimated_runtime: Estimated runtime (e.g., "3 minutes").
Returns:
Dictionary with production assembly notes.
"""
return {
"production": {
"title": title,
"total_scenes": total_scenes,
"estimated_runtime": estimated_runtime,
"status": "ready_for_production",
}
}
# ── Pipeline stages ──────────────────────────────────────────────────
concept_developer = Agent(
name="concept_developer",
model=settings.llm_model,
instructions=(
"You are a creative director. Develop a concept for a short film "
"based on the given theme. Use create_concept to document the "
"title, genre, and logline. Keep it concise and compelling."
),
tools=[create_concept],
)
scriptwriter = Agent(
name="scriptwriter",
model=settings.llm_model,
instructions=(
"You are a scriptwriter. Based on the concept from the previous "
"stage, write 3 short scenes using write_scene for each. "
"Include location, action, and brief dialogue."
),
tools=[write_scene],
)
visual_director = Agent(
name="visual_director",
model=settings.llm_model,
instructions=(
"You are a visual director. For each scene written by the "
"scriptwriter, use describe_visual to specify camera shots, "
"lighting, and visual mood. Create one visual spec per scene."
),
tools=[describe_visual],
)
audio_designer = Agent(
name="audio_designer",
model=settings.llm_model,
instructions=(
"You are an audio designer. For each scene, use specify_audio "
"to define the music mood and key sound effects. Match the "
"audio to the visual mood described by the visual director."
),
tools=[specify_audio],
)
producer = Agent(
name="producer",
model=settings.llm_model,
instructions=(
"You are the producer. Review all previous stages and use "
"assemble_production to create final production notes. "
"Summarize the complete short film with all creative elements."
),
tools=[assemble_production],
)
# Full pipeline using >> operator: concept → script → visuals → audio → assembly
pipeline = concept_developer >> scriptwriter >> visual_director >> audio_designer >> producer
if __name__ == "__main__":
with AgentRuntime() as runtime:
result = runtime.run(
pipeline,
"Create a 3-scene short film about a robot discovering music "
"for the first time in a post-apocalyptic world.",
)
result.print_result()
# Production pattern:
# 1. Deploy once during CI/CD:
# runtime.deploy(pipeline)
# CLI alternative:
# agentspan deploy --package examples.41_sequential_pipeline_tools
#
# 2. In a separate long-lived worker process:
# runtime.serve(pipeline)