Deployment commited on
Commit
cc1daf4
Β·
1 Parent(s): 67b2d30

Refactor: All agents on port 7860 with organized API endpoints

Browse files
Files changed (3) hide show
  1. API_ENDPOINTS.md +361 -0
  2. config.py +12 -9
  3. main.py +217 -89
API_ENDPOINTS.md ADDED
@@ -0,0 +1,361 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Multi-Agent Content Generation System - API Endpoints
2
+
3
+ **Base URL:** `http://localhost:7860`
4
+ **Port:** `7860` (all agents on single port)
5
+
6
+ ---
7
+
8
+ ## Health & Status
9
+
10
+ ### Health Check
11
+ ```
12
+ GET /health
13
+ ```
14
+ Returns system health status and current run ID.
15
+
16
+ **Response:**
17
+ ```json
18
+ {
19
+ "status": "healthy",
20
+ "run_id": "uuid",
21
+ "port": 7860
22
+ }
23
+ ```
24
+
25
+ ### Root Endpoint
26
+ ```
27
+ GET /
28
+ ```
29
+ Returns API information and available endpoints.
30
+
31
+ ---
32
+
33
+ ## Pipeline Endpoints
34
+
35
+ ### Execute Full Pipeline
36
+ ```
37
+ POST /api/pipeline/execute
38
+ ```
39
+ Execute the complete 7-stage content generation pipeline.
40
+
41
+ **Request Body:**
42
+ ```json
43
+ {
44
+ "user_brief": "string",
45
+ "season_arc_document": "string",
46
+ "character_bible": "string",
47
+ "world_building_document": "string",
48
+ "character_voice_guide": "string",
49
+ "style_guide": "string",
50
+ "continuity_log": "string",
51
+ "hook_brief": "string (optional)"
52
+ }
53
+ ```
54
+
55
+ **Response:**
56
+ ```json
57
+ {
58
+ "run_id": "uuid",
59
+ "status": "success",
60
+ "final_output": { ... },
61
+ "hf_output_url": "https://huggingface.co/...",
62
+ "hf_metadata_url": "https://huggingface.co/..."
63
+ }
64
+ ```
65
+
66
+ ### Get Pipeline Status
67
+ ```
68
+ GET /api/pipeline/status/{run_id}
69
+ ```
70
+ Get the status and state of a specific pipeline run.
71
+
72
+ **Response:**
73
+ ```json
74
+ {
75
+ "run_id": "uuid",
76
+ "status": "completed|failed|running",
77
+ "pipeline_state": { ... }
78
+ }
79
+ ```
80
+
81
+ ---
82
+
83
+ ## Agent Endpoints
84
+
85
+ All agents run on port 7860 with dedicated endpoints.
86
+
87
+ ### 1. Showrunner Agent
88
+ ```
89
+ POST /api/agents/showrunner
90
+ ```
91
+ Generate episode directive from user brief.
92
+
93
+ **Input:**
94
+ ```json
95
+ {
96
+ "user_brief": "string",
97
+ "season_arc_document": "string",
98
+ "character_bible": "string"
99
+ }
100
+ ```
101
+
102
+ **Output:**
103
+ ```json
104
+ {
105
+ "episode_directive": "string",
106
+ "story_premise": "string",
107
+ "tone_brief": "string",
108
+ "character_focus_notes": "string"
109
+ }
110
+ ```
111
+
112
+ ---
113
+
114
+ ### 2. Story Editor Agent
115
+ ```
116
+ POST /api/agents/story-editor
117
+ ```
118
+ Generate episode outline from directive.
119
+
120
+ **Input:**
121
+ ```json
122
+ {
123
+ "episode_directive": "string",
124
+ "series_continuity_log": "string",
125
+ "character_list": ["Alex", "Jordan", "Casey", "Morgan"]
126
+ }
127
+ ```
128
+
129
+ **Output:**
130
+ ```json
131
+ {
132
+ "episode_outline": "string",
133
+ "act_structure": "string",
134
+ "story_notes_for_writers": "string"
135
+ }
136
+ ```
137
+
138
+ ---
139
+
140
+ ### 3. Cultural Consultant Agent
141
+ ```
142
+ POST /api/agents/cultural-consultant
143
+ ```
144
+ Review outline for cultural accuracy.
145
+
146
+ **Input:**
147
+ ```json
148
+ {
149
+ "episode_outline": "string",
150
+ "world_building_document": "string",
151
+ "character_list": ["Alex", "Jordan", "Casey", "Morgan"]
152
+ }
153
+ ```
154
+
155
+ **Output:**
156
+ ```json
157
+ {
158
+ "cultural_accuracy_notes": "string",
159
+ "flagged_inaccuracies": ["issue1", "issue2"],
160
+ "approved_touchpoints": ["touchpoint1"],
161
+ "reference_suggestions": ["suggestion1"]
162
+ }
163
+ ```
164
+
165
+ ---
166
+
167
+ ### 4. Lead Writer Agent
168
+ ```
169
+ POST /api/agents/lead-writer
170
+ ```
171
+ Write episode script from outline and cultural notes.
172
+
173
+ **Input:**
174
+ ```json
175
+ {
176
+ "approved_outline": "string",
177
+ "cultural_consultant_notes": "string",
178
+ "character_voice_guide": "string",
179
+ "character_list": ["Alex", "Jordan", "Casey", "Morgan"],
180
+ "story_premise": "string"
181
+ }
182
+ ```
183
+
184
+ **Output:**
185
+ ```json
186
+ {
187
+ "full_episode_first_draft": "string",
188
+ "scene_descriptions": "string",
189
+ "dialogue": "string",
190
+ "stage_directions": "string"
191
+ }
192
+ ```
193
+
194
+ ---
195
+
196
+ ### 5. Dialogue Specialist Agent
197
+ ```
198
+ POST /api/agents/dialogue-specialist
199
+ ```
200
+ Polish dialogue in the script.
201
+
202
+ **Input:**
203
+ ```json
204
+ {
205
+ "first_draft_script": "string (must not be empty)",
206
+ "character_voice_guide": "string",
207
+ "character_list": ["Alex", "Jordan", "Casey", "Morgan"],
208
+ "dialect_slang_reference": "string"
209
+ }
210
+ ```
211
+
212
+ **Output:**
213
+ ```json
214
+ {
215
+ "dialogue_polished_script": "string",
216
+ "voice_consistency_notes": "string"
217
+ }
218
+ ```
219
+
220
+ ---
221
+
222
+ ### 6. Comedy Writer Agent
223
+ ```
224
+ POST /api/agents/comedy-writer
225
+ ```
226
+ Add humor and punch-ups to the script.
227
+
228
+ **Input:**
229
+ ```json
230
+ {
231
+ "dialogue_polished_script": "string (must not be empty)",
232
+ "hook_brief_from_showrunner": "string",
233
+ "character_list": ["Alex", "Jordan", "Casey", "Morgan"],
234
+ "tone_brief": "string"
235
+ }
236
+ ```
237
+
238
+ **Output:**
239
+ ```json
240
+ {
241
+ "comedy_sharpened_script": "string",
242
+ "punch_up_notes": "string",
243
+ "hook_rewrite_for_opening": "string"
244
+ }
245
+ ```
246
+
247
+ ---
248
+
249
+ ### 7. Proofreader Agent
250
+ ```
251
+ POST /api/agents/proofreader
252
+ ```
253
+ Final quality control on the script.
254
+
255
+ **Input:**
256
+ ```json
257
+ {
258
+ "comedy_sharpened_script": "string (must not be empty)",
259
+ "style_guide": "string",
260
+ "continuity_log": "string",
261
+ "character_list": ["Alex", "Jordan", "Casey", "Morgan"]
262
+ }
263
+ ```
264
+
265
+ **Output:**
266
+ ```json
267
+ {
268
+ "final_locked_script": "string",
269
+ "qc_report": {
270
+ "issues": [],
271
+ "style_alignment": "string",
272
+ "character_consistency": "string",
273
+ "formatting_notes": "string",
274
+ "recommendations": []
275
+ },
276
+ "continuity_log_update": "string"
277
+ }
278
+ ```
279
+
280
+ ---
281
+
282
+ ## API Usage Examples
283
+
284
+ ### Example 1: Execute Full Pipeline
285
+ ```bash
286
+ curl -X POST http://localhost:7860/api/pipeline/execute \
287
+ -H "Content-Type: application/json" \
288
+ -d '{
289
+ "user_brief": "A tech startup launches a new app",
290
+ "season_arc_document": "Season 1: The Rise",
291
+ "character_bible": "Alex (CEO), Jordan (CTO), Casey (Designer), Morgan (Marketer)",
292
+ "world_building_document": "Modern Silicon Valley",
293
+ "character_voice_guide": "Alex: sarcastic, Jordan: technical, Casey: perfectionist, Morgan: optimistic",
294
+ "style_guide": "Fast-paced, comedic, tech satire",
295
+ "continuity_log": "Episode 1: Team formation, Episode 2: First failure, Episode 3: Launch day"
296
+ }'
297
+ ```
298
+
299
+ ### Example 2: Call Individual Agent
300
+ ```bash
301
+ curl -X POST http://localhost:7860/api/agents/showrunner \
302
+ -H "Content-Type: application/json" \
303
+ -d '{
304
+ "user_brief": "A tech startup launches a new app",
305
+ "season_arc_document": "Season 1: The Rise",
306
+ "character_bible": "Alex (CEO), Jordan (CTO), Casey (Designer), Morgan (Marketer)"
307
+ }'
308
+ ```
309
+
310
+ ### Example 3: Check Pipeline Status
311
+ ```bash
312
+ curl -X GET http://localhost:7860/api/pipeline/status/0e35979c-8240-4451-a693-6bed1516aa4d
313
+ ```
314
+
315
+ ---
316
+
317
+ ## Error Handling
318
+
319
+ All endpoints return appropriate HTTP status codes:
320
+
321
+ - **200 OK** - Successful request
322
+ - **400 Bad Request** - Invalid input
323
+ - **404 Not Found** - Resource not found
324
+ - **500 Internal Server Error** - Server error
325
+
326
+ Error responses include a detail message:
327
+ ```json
328
+ {
329
+ "detail": "Error message explaining what went wrong"
330
+ }
331
+ ```
332
+
333
+ ---
334
+
335
+ ## Documentation
336
+
337
+ - **Interactive API Docs:** `http://localhost:7860/docs` (Swagger UI)
338
+ - **Alternative Docs:** `http://localhost:7860/redoc` (ReDoc)
339
+
340
+ ---
341
+
342
+ ## Architecture
343
+
344
+ ```
345
+ Port 7860 (Single Port)
346
+ β”œβ”€β”€ /health
347
+ β”œβ”€β”€ /
348
+ β”œβ”€β”€ /api/pipeline/
349
+ β”‚ β”œβ”€β”€ execute
350
+ β”‚ └── status/{run_id}
351
+ └── /api/agents/
352
+ β”œβ”€β”€ showrunner
353
+ β”œβ”€β”€ story-editor
354
+ β”œβ”€β”€ cultural-consultant
355
+ β”œβ”€β”€ lead-writer
356
+ β”œβ”€β”€ dialogue-specialist
357
+ β”œβ”€β”€ comedy-writer
358
+ └── proofreader
359
+ ```
360
+
361
+ All agents communicate through the orchestrator and share state via the pipeline.
config.py CHANGED
@@ -28,17 +28,19 @@ class Settings(BaseSettings):
28
  data_dir: str = "./data"
29
  output_dir: str = "./output"
30
  log_dir: str = "./logs"
31
- port: int = 8000
32
  host: str = "0.0.0.0"
33
 
34
- # Agent Ports
35
- showrunner_port: int = 8001
36
- story_editor_port: int = 8002
37
- cultural_consultant_port: int = 8003
38
- lead_writer_port: int = 8004
39
- dialogue_specialist_port: int = 8005
40
- comedy_writer_port: int = 8006
41
- proofreader_port: int = 8007
 
 
42
 
43
  # Logging
44
  log_level: str = "INFO"
@@ -77,6 +79,7 @@ class Settings(BaseSettings):
77
  logger.info("Configuration loaded successfully")
78
  logger.info(f"Model: {self.model_name}")
79
  logger.info(f"Dataset: {self.huggingface_dataset}")
 
80
 
81
 
82
  # Load settings
 
28
  data_dir: str = "./data"
29
  output_dir: str = "./output"
30
  log_dir: str = "./logs"
31
+ port: int = 7860 # All agents run on this single port
32
  host: str = "0.0.0.0"
33
 
34
+ # Agent Endpoints (all on port 7860)
35
+ # POST /api/agents/showrunner
36
+ # POST /api/agents/story-editor
37
+ # POST /api/agents/cultural-consultant
38
+ # POST /api/agents/lead-writer
39
+ # POST /api/agents/dialogue-specialist
40
+ # POST /api/agents/comedy-writer
41
+ # POST /api/agents/proofreader
42
+ # POST /api/pipeline/execute
43
+ # GET /api/pipeline/status/{run_id}
44
 
45
  # Logging
46
  log_level: str = "INFO"
 
79
  logger.info("Configuration loaded successfully")
80
  logger.info(f"Model: {self.model_name}")
81
  logger.info(f"Dataset: {self.huggingface_dataset}")
82
+ logger.info(f"Port: {self.port} (all agents on this single port)")
83
 
84
 
85
  # Load settings
main.py CHANGED
@@ -1,4 +1,15 @@
1
- """FastAPI server for the multi-agent content generation system."""
 
 
 
 
 
 
 
 
 
 
 
2
  import logging
3
  from fastapi import FastAPI, HTTPException
4
  from pydantic import BaseModel
@@ -17,7 +28,7 @@ logger = logging.getLogger(__name__)
17
  # Initialize FastAPI app
18
  app = FastAPI(
19
  title="Multi-Agent Content Generation System",
20
- description="API-first system for collaborative content generation using poolside/laguna-m.1:free",
21
  version="1.0.0",
22
  )
23
 
@@ -51,21 +62,54 @@ class HealthResponse(BaseModel):
51
  """Health check response."""
52
  status: str
53
  run_id: str
 
54
 
55
 
56
- # Endpoints
 
 
 
57
  @app.get("/health", response_model=HealthResponse)
58
  async def health_check():
59
  """Health check endpoint."""
60
  return {
61
  "status": "healthy",
62
  "run_id": orchestrator.run_id,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  }
64
 
65
 
66
- @app.post("/api/v1/pipeline/execute", response_model=PipelineResponse)
 
 
 
 
67
  async def execute_pipeline(request: PipelineRequest):
68
  """Execute the full content generation pipeline.
 
 
 
69
 
70
  Args:
71
  request: Pipeline execution request with all required inputs
@@ -74,7 +118,7 @@ async def execute_pipeline(request: PipelineRequest):
74
  Pipeline execution result with final output and URLs
75
  """
76
  try:
77
- logger.info(f"Received pipeline execution request: {request.user_brief[:50]}...")
78
 
79
  result = orchestrator.execute_pipeline(
80
  user_brief=request.user_brief,
@@ -96,157 +140,241 @@ async def execute_pipeline(request: PipelineRequest):
96
  }
97
 
98
  except Exception as e:
99
- logger.error(f"Pipeline execution error: {str(e)}")
100
  raise HTTPException(status_code=500, detail=str(e))
101
 
102
 
103
- @app.post("/api/v1/showrunner/generate_directive")
104
- async def generate_directive(request: dict):
105
- """Generate episode directive from user brief.
 
 
 
106
 
107
  Args:
108
- request: Dictionary with user_brief, season_arc_document, character_bible
109
 
110
  Returns:
111
- Generated directive
112
  """
113
  try:
114
- result = orchestrator.showrunner.generate_directive(request)
115
- return result
 
 
 
 
 
 
116
  except Exception as e:
117
  raise HTTPException(status_code=500, detail=str(e))
118
 
119
 
120
- @app.post("/api/v1/story_editor/generate_outline")
121
- async def generate_outline(request: dict):
122
- """Generate episode outline from directive.
123
-
124
- Args:
125
- request: Dictionary with episode_directive, series_continuity_log
126
 
127
- Returns:
128
- Generated outline
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  """
130
  try:
131
- result = orchestrator.story_editor.generate_outline(request)
 
132
  return result
133
  except Exception as e:
 
134
  raise HTTPException(status_code=500, detail=str(e))
135
 
136
 
137
- @app.post("/api/v1/cultural_consultant/review_outline")
138
- async def review_outline(request: dict):
139
- """Review outline for cultural accuracy.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
 
141
- Args:
142
- request: Dictionary with episode_outline, world_building_document
143
 
144
- Returns:
145
- Cultural review and recommendations
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  """
147
  try:
 
148
  result = orchestrator.cultural_consultant.review_outline(request)
149
  return result
150
  except Exception as e:
 
151
  raise HTTPException(status_code=500, detail=str(e))
152
 
153
 
154
- @app.post("/api/v1/lead_writer/write_script")
155
- async def write_script(request: dict):
156
- """Write episode script from outline and cultural notes.
157
-
158
- Args:
159
- request: Dictionary with approved_outline, cultural_consultant_notes, character_voice_guide
160
-
161
- Returns:
162
- Generated script
 
 
 
 
 
 
 
 
 
 
163
  """
164
  try:
 
165
  result = orchestrator.lead_writer.write_script(request)
166
  return result
167
  except Exception as e:
 
168
  raise HTTPException(status_code=500, detail=str(e))
169
 
170
 
171
- @app.post("/api/v1/dialogue_specialist/polish_dialogue")
172
- async def polish_dialogue(request: dict):
173
- """Polish dialogue in the script.
174
-
175
- Args:
176
- request: Dictionary with first_draft_script, character_voice_guide, dialect_slang_reference
177
-
178
- Returns:
179
- Polished script
 
 
 
 
 
 
 
180
  """
181
  try:
 
182
  result = orchestrator.dialogue_specialist.polish_dialogue(request)
183
  return result
184
  except Exception as e:
 
185
  raise HTTPException(status_code=500, detail=str(e))
186
 
187
 
188
- @app.post("/api/v1/comedy_writer/add_humor")
189
- async def add_humor(request: dict):
190
- """Add humor and punch-ups to the script.
191
-
192
- Args:
193
- request: Dictionary with dialogue_polished_script, hook_brief_from_showrunner
194
-
195
- Returns:
196
- Comedy-enhanced script
 
 
 
 
 
 
 
 
197
  """
198
  try:
 
199
  result = orchestrator.comedy_writer.add_humor(request)
200
  return result
201
  except Exception as e:
 
202
  raise HTTPException(status_code=500, detail=str(e))
203
 
204
 
205
- @app.post("/api/v1/proofreader/final_qc")
206
- async def final_qc(request: dict):
207
- """Perform final quality control on the script.
208
-
209
- Args:
210
- request: Dictionary with comedy_sharpened_script, style_guide, continuity_log
211
-
212
- Returns:
213
- Final QC report and locked script
 
 
 
 
 
 
 
 
214
  """
215
  try:
 
216
  result = orchestrator.proofreader.final_qc(request)
217
  return result
218
  except Exception as e:
 
219
  raise HTTPException(status_code=500, detail=str(e))
220
 
221
 
222
- @app.get("/api/v1/pipeline/status/{run_id}")
223
- async def get_pipeline_status(run_id: str):
224
- """Get the status of a pipeline run.
225
-
226
- Args:
227
- run_id: The run ID to check
228
-
229
- Returns:
230
- Pipeline status and state
231
- """
232
- try:
233
- # In a real system, this would query a database
234
- # For now, we return the current orchestrator state if it matches
235
- if run_id == orchestrator.run_id:
236
- return {
237
- "run_id": run_id,
238
- "status": orchestrator.pipeline_state.get("status", "unknown"),
239
- "pipeline_state": orchestrator.pipeline_state,
240
- }
241
- else:
242
- raise HTTPException(status_code=404, detail="Run ID not found")
243
- except Exception as e:
244
- raise HTTPException(status_code=500, detail=str(e))
245
-
246
 
247
  if __name__ == "__main__":
248
  import uvicorn
249
 
 
 
 
 
 
250
  uvicorn.run(
251
  app,
252
  host=settings.host,
 
1
+ """FastAPI server for the multi-agent content generation system.
2
+
3
+ All agents run on port 7860 with different API endpoints:
4
+ - /api/agents/showrunner - Generate episode directive
5
+ - /api/agents/story-editor - Generate episode outline
6
+ - /api/agents/cultural-consultant - Review for cultural accuracy
7
+ - /api/agents/lead-writer - Write episode script
8
+ - /api/agents/dialogue-specialist - Polish dialogue
9
+ - /api/agents/comedy-writer - Add humor and punch-ups
10
+ - /api/agents/proofreader - Final quality control
11
+ - /api/pipeline - Execute full pipeline
12
+ """
13
  import logging
14
  from fastapi import FastAPI, HTTPException
15
  from pydantic import BaseModel
 
28
  # Initialize FastAPI app
29
  app = FastAPI(
30
  title="Multi-Agent Content Generation System",
31
+ description="API-first system for collaborative content generation using poolside/laguna-m.1:free. All agents on port 7860.",
32
  version="1.0.0",
33
  )
34
 
 
62
  """Health check response."""
63
  status: str
64
  run_id: str
65
+ port: int
66
 
67
 
68
+ # ─────────────────────────────────────────────────────────────────────────────
69
+ # HEALTH & STATUS ENDPOINTS
70
+ # ─────────────────────────────────────────────────────────────────────────────
71
+
72
  @app.get("/health", response_model=HealthResponse)
73
  async def health_check():
74
  """Health check endpoint."""
75
  return {
76
  "status": "healthy",
77
  "run_id": orchestrator.run_id,
78
+ "port": settings.port,
79
+ }
80
+
81
+
82
+ @app.get("/")
83
+ async def root():
84
+ """Root endpoint with API documentation."""
85
+ return {
86
+ "service": "Multi-Agent Content Generation System",
87
+ "version": "1.0.0",
88
+ "port": settings.port,
89
+ "docs": "/docs",
90
+ "agents": {
91
+ "showrunner": "/api/agents/showrunner",
92
+ "story_editor": "/api/agents/story-editor",
93
+ "cultural_consultant": "/api/agents/cultural-consultant",
94
+ "lead_writer": "/api/agents/lead-writer",
95
+ "dialogue_specialist": "/api/agents/dialogue-specialist",
96
+ "comedy_writer": "/api/agents/comedy-writer",
97
+ "proofreader": "/api/agents/proofreader",
98
+ },
99
+ "pipeline": "/api/pipeline/execute",
100
  }
101
 
102
 
103
+ # ─────────────────────────────────────────────────────────────────────────────
104
+ # PIPELINE ENDPOINTS (Port 7860)
105
+ # ─────────────────────────────────────────────────────────────────────────────
106
+
107
+ @app.post("/api/pipeline/execute", response_model=PipelineResponse)
108
  async def execute_pipeline(request: PipelineRequest):
109
  """Execute the full content generation pipeline.
110
+
111
+ Endpoint: POST /api/pipeline/execute
112
+ Port: 7860
113
 
114
  Args:
115
  request: Pipeline execution request with all required inputs
 
118
  Pipeline execution result with final output and URLs
119
  """
120
  try:
121
+ logger.info(f"[PIPELINE] Received execution request: {request.user_brief[:50]}...")
122
 
123
  result = orchestrator.execute_pipeline(
124
  user_brief=request.user_brief,
 
140
  }
141
 
142
  except Exception as e:
143
+ logger.error(f"[PIPELINE] Execution error: {str(e)}")
144
  raise HTTPException(status_code=500, detail=str(e))
145
 
146
 
147
+ @app.get("/api/pipeline/status/{run_id}")
148
+ async def get_pipeline_status(run_id: str):
149
+ """Get the status of a pipeline run.
150
+
151
+ Endpoint: GET /api/pipeline/status/{run_id}
152
+ Port: 7860
153
 
154
  Args:
155
+ run_id: The run ID to check
156
 
157
  Returns:
158
+ Pipeline status and state
159
  """
160
  try:
161
+ if run_id == orchestrator.run_id:
162
+ return {
163
+ "run_id": run_id,
164
+ "status": orchestrator.pipeline_state.get("status", "unknown"),
165
+ "pipeline_state": orchestrator.pipeline_state,
166
+ }
167
+ else:
168
+ raise HTTPException(status_code=404, detail="Run ID not found")
169
  except Exception as e:
170
  raise HTTPException(status_code=500, detail=str(e))
171
 
172
 
173
+ # ─────────────────────────────────────────────────────────────────────────────
174
+ # AGENT ENDPOINTS (Port 7860)
175
+ # ─────────────────────────────────────────────────────────────────────────────
 
 
 
176
 
177
+ @app.post("/api/agents/showrunner")
178
+ async def showrunner_endpoint(request: dict):
179
+ """Showrunner Agent: Generate episode directive.
180
+
181
+ Endpoint: POST /api/agents/showrunner
182
+ Port: 7860
183
+
184
+ Input:
185
+ - user_brief: Initial user brief
186
+ - season_arc_document: Season context
187
+ - character_bible: Character definitions
188
+
189
+ Output:
190
+ - episode_directive: Generated directive
191
+ - story_premise: Story premise
192
+ - tone_brief: Tone brief
193
+ - character_focus_notes: Character notes
194
  """
195
  try:
196
+ logger.info("[SHOWRUNNER] Processing directive generation")
197
+ result = orchestrator.showrunner.generate_directive(request)
198
  return result
199
  except Exception as e:
200
+ logger.error(f"[SHOWRUNNER] Error: {str(e)}")
201
  raise HTTPException(status_code=500, detail=str(e))
202
 
203
 
204
+ @app.post("/api/agents/story-editor")
205
+ async def story_editor_endpoint(request: dict):
206
+ """Story Editor Agent: Generate episode outline.
207
+
208
+ Endpoint: POST /api/agents/story-editor
209
+ Port: 7860
210
+
211
+ Input:
212
+ - episode_directive: From Showrunner
213
+ - series_continuity_log: Continuity reference
214
+ - character_list: Valid character names
215
+
216
+ Output:
217
+ - episode_outline: Generated outline
218
+ - act_structure: Act breakdown
219
+ - story_notes_for_writers: Story notes
220
+ """
221
+ try:
222
+ logger.info("[STORY-EDITOR] Processing outline generation")
223
+ result = orchestrator.story_editor.generate_outline(request)
224
+ return result
225
+ except Exception as e:
226
+ logger.error(f"[STORY-EDITOR] Error: {str(e)}")
227
+ raise HTTPException(status_code=500, detail=str(e))
228
 
 
 
229
 
230
+ @app.post("/api/agents/cultural-consultant")
231
+ async def cultural_consultant_endpoint(request: dict):
232
+ """Cultural Consultant Agent: Review for cultural accuracy.
233
+
234
+ Endpoint: POST /api/agents/cultural-consultant
235
+ Port: 7860
236
+
237
+ Input:
238
+ - episode_outline: From Story Editor
239
+ - world_building_document: World context
240
+ - character_list: Valid character names
241
+
242
+ Output:
243
+ - cultural_accuracy_notes: Accuracy notes
244
+ - flagged_inaccuracies: Issues found
245
+ - approved_touchpoints: Approved elements
246
+ - reference_suggestions: Suggestions
247
  """
248
  try:
249
+ logger.info("[CULTURAL-CONSULTANT] Processing cultural review")
250
  result = orchestrator.cultural_consultant.review_outline(request)
251
  return result
252
  except Exception as e:
253
+ logger.error(f"[CULTURAL-CONSULTANT] Error: {str(e)}")
254
  raise HTTPException(status_code=500, detail=str(e))
255
 
256
 
257
+ @app.post("/api/agents/lead-writer")
258
+ async def lead_writer_endpoint(request: dict):
259
+ """Lead Writer Agent: Write episode script.
260
+
261
+ Endpoint: POST /api/agents/lead-writer
262
+ Port: 7860
263
+
264
+ Input:
265
+ - approved_outline: From Story Editor
266
+ - cultural_consultant_notes: From Cultural Consultant
267
+ - character_voice_guide: Character voice definitions
268
+ - character_list: Valid character names
269
+ - story_premise: Story premise from Showrunner
270
+
271
+ Output:
272
+ - full_episode_first_draft: Complete script
273
+ - scene_descriptions: Scene descriptions
274
+ - dialogue: Dialogue content
275
+ - stage_directions: Stage directions
276
  """
277
  try:
278
+ logger.info("[LEAD-WRITER] Processing script writing")
279
  result = orchestrator.lead_writer.write_script(request)
280
  return result
281
  except Exception as e:
282
+ logger.error(f"[LEAD-WRITER] Error: {str(e)}")
283
  raise HTTPException(status_code=500, detail=str(e))
284
 
285
 
286
+ @app.post("/api/agents/dialogue-specialist")
287
+ async def dialogue_specialist_endpoint(request: dict):
288
+ """Dialogue Specialist Agent: Polish dialogue.
289
+
290
+ Endpoint: POST /api/agents/dialogue-specialist
291
+ Port: 7860
292
+
293
+ Input:
294
+ - first_draft_script: From Lead Writer
295
+ - character_voice_guide: Character voice definitions
296
+ - character_list: Valid character names
297
+ - dialect_slang_reference: Reference material
298
+
299
+ Output:
300
+ - dialogue_polished_script: Polished script
301
+ - voice_consistency_notes: Voice notes
302
  """
303
  try:
304
+ logger.info("[DIALOGUE-SPECIALIST] Processing dialogue polish")
305
  result = orchestrator.dialogue_specialist.polish_dialogue(request)
306
  return result
307
  except Exception as e:
308
+ logger.error(f"[DIALOGUE-SPECIALIST] Error: {str(e)}")
309
  raise HTTPException(status_code=500, detail=str(e))
310
 
311
 
312
+ @app.post("/api/agents/comedy-writer")
313
+ async def comedy_writer_endpoint(request: dict):
314
+ """Comedy Writer Agent: Add humor and punch-ups.
315
+
316
+ Endpoint: POST /api/agents/comedy-writer
317
+ Port: 7860
318
+
319
+ Input:
320
+ - dialogue_polished_script: From Dialogue Specialist
321
+ - hook_brief_from_showrunner: Hook context
322
+ - character_list: Valid character names
323
+ - tone_brief: Tone reference
324
+
325
+ Output:
326
+ - comedy_sharpened_script: Comedy-enhanced script
327
+ - punch_up_notes: Notes on changes
328
+ - hook_rewrite_for_opening: Opening hook
329
  """
330
  try:
331
+ logger.info("[COMEDY-WRITER] Processing humor addition")
332
  result = orchestrator.comedy_writer.add_humor(request)
333
  return result
334
  except Exception as e:
335
+ logger.error(f"[COMEDY-WRITER] Error: {str(e)}")
336
  raise HTTPException(status_code=500, detail=str(e))
337
 
338
 
339
+ @app.post("/api/agents/proofreader")
340
+ async def proofreader_endpoint(request: dict):
341
+ """Proofreader Agent: Final quality control.
342
+
343
+ Endpoint: POST /api/agents/proofreader
344
+ Port: 7860
345
+
346
+ Input:
347
+ - comedy_sharpened_script: From Comedy Writer
348
+ - style_guide: Style reference
349
+ - continuity_log: Continuity tracking
350
+ - character_list: Valid character names
351
+
352
+ Output:
353
+ - final_locked_script: Final script
354
+ - qc_report: Quality control report
355
+ - continuity_log_update: Updated continuity log
356
  """
357
  try:
358
+ logger.info("[PROOFREADER] Processing final QC")
359
  result = orchestrator.proofreader.final_qc(request)
360
  return result
361
  except Exception as e:
362
+ logger.error(f"[PROOFREADER] Error: {str(e)}")
363
  raise HTTPException(status_code=500, detail=str(e))
364
 
365
 
366
+ # ──────────────────────────────────────────────────────────���──────────────────
367
+ # SERVER STARTUP
368
+ # ─────────────────────────────────────────────────────────────────────────────
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
369
 
370
  if __name__ == "__main__":
371
  import uvicorn
372
 
373
+ logger.info(f"Starting Multi-Agent System on port {settings.port}")
374
+ logger.info("All agents available at http://localhost:7860/api/agents/*")
375
+ logger.info("Full pipeline available at http://localhost:7860/api/pipeline/execute")
376
+ logger.info("API documentation at http://localhost:7860/docs")
377
+
378
  uvicorn.run(
379
  app,
380
  host=settings.host,