@mytechtoday/augment-extensions 2.3.6 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -21
- package/cli/dist/cli.js +2 -0
- package/cli/dist/cli.js.map +1 -1
- package/cli/dist/commands/generate-shot-list/formatter/markdown-formatter.d.ts +5 -0
- package/cli/dist/commands/generate-shot-list/formatter/markdown-formatter.d.ts.map +1 -1
- package/cli/dist/commands/generate-shot-list/formatter/markdown-formatter.js +89 -1
- package/cli/dist/commands/generate-shot-list/formatter/markdown-formatter.js.map +1 -1
- package/cli/dist/commands/generate-shot-list/generator/ai-blocking-extractor.d.ts +58 -0
- package/cli/dist/commands/generate-shot-list/generator/ai-blocking-extractor.d.ts.map +1 -0
- package/cli/dist/commands/generate-shot-list/generator/ai-blocking-extractor.js +275 -0
- package/cli/dist/commands/generate-shot-list/generator/ai-blocking-extractor.js.map +1 -0
- package/cli/dist/commands/generate-shot-list/generator/ai-entity-extractor.d.ts +41 -0
- package/cli/dist/commands/generate-shot-list/generator/ai-entity-extractor.d.ts.map +1 -0
- package/cli/dist/commands/generate-shot-list/generator/ai-entity-extractor.js +155 -0
- package/cli/dist/commands/generate-shot-list/generator/ai-entity-extractor.js.map +1 -0
- package/cli/dist/commands/generate-shot-list/generator/context-builder.d.ts +65 -2
- package/cli/dist/commands/generate-shot-list/generator/context-builder.d.ts.map +1 -1
- package/cli/dist/commands/generate-shot-list/generator/context-builder.js +394 -98
- package/cli/dist/commands/generate-shot-list/generator/context-builder.js.map +1 -1
- package/cli/dist/commands/generate-shot-list/generator/index.d.ts +59 -1
- package/cli/dist/commands/generate-shot-list/generator/index.d.ts.map +1 -1
- package/cli/dist/commands/generate-shot-list/generator/index.js +364 -34
- package/cli/dist/commands/generate-shot-list/generator/index.js.map +1 -1
- package/cli/dist/commands/generate-shot-list/generator/types.d.ts +3 -2
- package/cli/dist/commands/generate-shot-list/generator/types.d.ts.map +1 -1
- package/cli/dist/commands/generate-shot-list/generator/validator.d.ts +33 -0
- package/cli/dist/commands/generate-shot-list/generator/validator.d.ts.map +1 -1
- package/cli/dist/commands/generate-shot-list/generator/validator.js +167 -0
- package/cli/dist/commands/generate-shot-list/generator/validator.js.map +1 -1
- package/cli/dist/commands/generate-shot-list/help-text.d.ts +1 -1
- package/cli/dist/commands/generate-shot-list/help-text.d.ts.map +1 -1
- package/cli/dist/commands/generate-shot-list/help-text.js +11 -0
- package/cli/dist/commands/generate-shot-list/help-text.js.map +1 -1
- package/cli/dist/commands/generate-shot-list.d.ts +1 -0
- package/cli/dist/commands/generate-shot-list.d.ts.map +1 -1
- package/cli/dist/commands/generate-shot-list.js +7 -4
- package/cli/dist/commands/generate-shot-list.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AI-Powered Blocking Extractor
|
|
4
|
+
*
|
|
5
|
+
* Uses Claude Sonnet 4.6 to extract detailed character blocking and spatial positions
|
|
6
|
+
* from screenplay action lines. Infers stage positions, relative positions, and
|
|
7
|
+
* maintains spatial consistency across shots.
|
|
8
|
+
*/
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.AIBlockingExtractor = void 0;
|
|
14
|
+
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
15
|
+
class AIBlockingExtractor {
|
|
16
|
+
constructor(apiKey, styleGuidelines) {
|
|
17
|
+
this.characterDescriptionCache = new Map();
|
|
18
|
+
this.styleGuidelines = null; // MergedStyleGuidelines type
|
|
19
|
+
this.client = new sdk_1.default({
|
|
20
|
+
apiKey: apiKey || process.env.ANTHROPIC_API_KEY,
|
|
21
|
+
});
|
|
22
|
+
this.styleGuidelines = styleGuidelines || null;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Clear the character description cache (call at start of new screenplay)
|
|
26
|
+
*/
|
|
27
|
+
clearCache() {
|
|
28
|
+
this.characterDescriptionCache.clear();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get cached character description
|
|
32
|
+
*/
|
|
33
|
+
getCachedDescription(characterName) {
|
|
34
|
+
return this.characterDescriptionCache.get(characterName);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Extract blocking, set description, and actions from action lines using AI
|
|
38
|
+
*/
|
|
39
|
+
async extractBlocking(actionLines, characterNames, previousPositions) {
|
|
40
|
+
const actionText = actionLines.join('\n');
|
|
41
|
+
// Identify which characters need descriptions (not in cache)
|
|
42
|
+
const charactersNeedingDescriptions = characterNames.filter(name => !this.characterDescriptionCache.has(name));
|
|
43
|
+
const prompt = this.buildBlockingPrompt(actionText, characterNames, previousPositions, charactersNeedingDescriptions);
|
|
44
|
+
try {
|
|
45
|
+
const response = await this.client.messages.create({
|
|
46
|
+
model: 'claude-sonnet-4-6',
|
|
47
|
+
max_tokens: 4096, // Increased for verbose descriptions
|
|
48
|
+
temperature: 0.0, // Deterministic for consistency
|
|
49
|
+
messages: [{
|
|
50
|
+
role: 'user',
|
|
51
|
+
content: prompt
|
|
52
|
+
}]
|
|
53
|
+
});
|
|
54
|
+
const content = response.content[0];
|
|
55
|
+
if (content.type === 'text') {
|
|
56
|
+
const result = this.parseBlockingResponse(content.text, characterNames);
|
|
57
|
+
// Cache new character descriptions
|
|
58
|
+
for (const desc of result.characterDescriptions) {
|
|
59
|
+
if (!this.characterDescriptionCache.has(desc.character)) {
|
|
60
|
+
this.characterDescriptionCache.set(desc.character, desc);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Add cached descriptions for characters that didn't need new ones
|
|
64
|
+
for (const name of characterNames) {
|
|
65
|
+
const cached = this.characterDescriptionCache.get(name);
|
|
66
|
+
if (cached && !result.characterDescriptions.find(d => d.character === name)) {
|
|
67
|
+
result.characterDescriptions.push(cached);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
throw new Error('Unexpected response format from AI');
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
console.error('AI blocking extraction failed:', error);
|
|
76
|
+
// Fallback to basic extraction
|
|
77
|
+
return this.fallbackExtraction(actionLines, characterNames);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Build prompt for AI blocking extraction
|
|
82
|
+
*/
|
|
83
|
+
buildBlockingPrompt(actionText, characterNames, previousPositions, charactersNeedingDescriptions) {
|
|
84
|
+
let prompt = `You are a screenplay blocking analyzer. Extract character positions, set descriptions, and actions from the following action lines.
|
|
85
|
+
|
|
86
|
+
**Action Lines:**
|
|
87
|
+
${actionText}
|
|
88
|
+
|
|
89
|
+
**Characters in Scene:**
|
|
90
|
+
${characterNames.join(', ')}
|
|
91
|
+
|
|
92
|
+
`;
|
|
93
|
+
if (previousPositions && previousPositions.size > 0) {
|
|
94
|
+
prompt += `**Previous Character Positions (maintain unless explicitly changed):**
|
|
95
|
+
`;
|
|
96
|
+
for (const [name, pos] of previousPositions.entries()) {
|
|
97
|
+
prompt += `- ${name}: ${pos.position}`;
|
|
98
|
+
if (pos.stagePosition)
|
|
99
|
+
prompt += ` (${pos.stagePosition})`;
|
|
100
|
+
prompt += '\n';
|
|
101
|
+
}
|
|
102
|
+
prompt += '\n';
|
|
103
|
+
}
|
|
104
|
+
// Add cached character descriptions to reduce redundant generation
|
|
105
|
+
const cachedDescriptions = [];
|
|
106
|
+
for (const name of characterNames) {
|
|
107
|
+
const cached = this.characterDescriptionCache.get(name);
|
|
108
|
+
if (cached) {
|
|
109
|
+
cachedDescriptions.push(`- ${name}: ${cached.physicalAppearance.substring(0, 100)}... (wardrobe: ${cached.wardrobe.substring(0, 100)}...)`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (cachedDescriptions.length > 0) {
|
|
113
|
+
prompt += `**Existing Character Descriptions (DO NOT regenerate these):**
|
|
114
|
+
${cachedDescriptions.join('\n')}
|
|
115
|
+
|
|
116
|
+
`;
|
|
117
|
+
}
|
|
118
|
+
// Add style guidelines if available
|
|
119
|
+
if (this.styleGuidelines) {
|
|
120
|
+
prompt += `**Cinematic Style Guidelines:**
|
|
121
|
+
`;
|
|
122
|
+
// Add applied styles
|
|
123
|
+
if (this.styleGuidelines.appliedStyles && this.styleGuidelines.appliedStyles.length > 0) {
|
|
124
|
+
prompt += `Active Styles: ${this.styleGuidelines.appliedStyles.join(', ')}\n\n`;
|
|
125
|
+
}
|
|
126
|
+
// Add visual characteristics
|
|
127
|
+
if (this.styleGuidelines.visualCharacteristics) {
|
|
128
|
+
const vc = this.styleGuidelines.visualCharacteristics;
|
|
129
|
+
if (vc.colorPalette && vc.colorPalette.length > 0) {
|
|
130
|
+
prompt += `Color Palette: ${vc.colorPalette.join(', ')}\n`;
|
|
131
|
+
}
|
|
132
|
+
if (vc.lighting && vc.lighting.length > 0) {
|
|
133
|
+
prompt += `Lighting: ${vc.lighting.join(', ')}\n`;
|
|
134
|
+
}
|
|
135
|
+
if (vc.composition && vc.composition.length > 0) {
|
|
136
|
+
prompt += `Composition: ${vc.composition.join(', ')}\n`;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Add character blocking style
|
|
140
|
+
if (this.styleGuidelines.characterBlocking) {
|
|
141
|
+
const cb = this.styleGuidelines.characterBlocking;
|
|
142
|
+
if (cb.staging && cb.staging.length > 0) {
|
|
143
|
+
prompt += `Staging: ${cb.staging.join(', ')}\n`;
|
|
144
|
+
}
|
|
145
|
+
if (cb.movement && cb.movement.length > 0) {
|
|
146
|
+
prompt += `Movement: ${cb.movement.join(', ')}\n`;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
prompt += `\n**IMPORTANT**: Apply these style guidelines to ALL descriptions (set, characters, wardrobe). Descriptions should reflect the visual language and aesthetic of the active cinematic style.\n\n`;
|
|
150
|
+
}
|
|
151
|
+
const needsDescriptions = charactersNeedingDescriptions && charactersNeedingDescriptions.length > 0;
|
|
152
|
+
prompt += `**Instructions:**
|
|
153
|
+
1. **Character Blocking**: For each character, extract their detailed spatial position
|
|
154
|
+
- Include stage position (stage left/right/center, upstage/downstage/center stage)
|
|
155
|
+
- Include relative positions (beside X, behind Y, at Z)
|
|
156
|
+
- Include action/posture (sits, stands, walks, etc.)
|
|
157
|
+
- Infer positions when not explicit (e.g., "beside her" → "beside CAPTAIN")
|
|
158
|
+
- Infer stage positions for set pieces (e.g., "tactical station" → "stage left, upstage")
|
|
159
|
+
- Use best guess for ambiguous positions based on typical stage layouts
|
|
160
|
+
|
|
161
|
+
`;
|
|
162
|
+
if (needsDescriptions) {
|
|
163
|
+
prompt += `2. **Character Descriptions**: ONLY for these NEW characters: ${charactersNeedingDescriptions.join(', ')}
|
|
164
|
+
- Physical Appearance (200-800 characters): Detailed physical description including face, body, age, distinguishing features
|
|
165
|
+
- Wardrobe (200-800 characters): Detailed clothing description including colors, style, materials, accessories
|
|
166
|
+
- Emotion (optional): Current emotional state if evident
|
|
167
|
+
- Expand on any hints in the text with rich cinematic details
|
|
168
|
+
- Make descriptions vivid and immersive
|
|
169
|
+
- IMPORTANT: Aim for 200-800 characters per character field
|
|
170
|
+
- DO NOT generate descriptions for characters already listed above
|
|
171
|
+
|
|
172
|
+
`;
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
prompt += `2. **Character Descriptions**: All characters already have descriptions (see above). DO NOT generate new ones.
|
|
176
|
+
|
|
177
|
+
`;
|
|
178
|
+
}
|
|
179
|
+
prompt += `3. **Set Description**: Create a DETAILED, VERBOSE environment description (400-800 characters)
|
|
180
|
+
- Expand on the basic set description with rich visual details
|
|
181
|
+
- Describe physical environment (walls, doors, furniture, props, materials, textures)
|
|
182
|
+
- Describe lighting, atmosphere, mood, visual style
|
|
183
|
+
- Add cinematic details that enhance the scene
|
|
184
|
+
- Make it vivid and immersive
|
|
185
|
+
- NO character positions or actions
|
|
186
|
+
- IMPORTANT: Aim for 400-800 characters of detailed description
|
|
187
|
+
|
|
188
|
+
4. **Character Actions**: Extract ONLY character movements and actions
|
|
189
|
+
- Movements (walks, runs, enters, exits)
|
|
190
|
+
- Physical actions (picks up, opens, closes)
|
|
191
|
+
- NOT static positions (sits, stands at)
|
|
192
|
+
|
|
193
|
+
5. **Sound Effects**: Extract sound effect descriptions
|
|
194
|
+
- Sounds, noises, music
|
|
195
|
+
- Format: "SOUND EFFECT: description"
|
|
196
|
+
|
|
197
|
+
**Output Format (JSON):**
|
|
198
|
+
\`\`\`json
|
|
199
|
+
{
|
|
200
|
+
"characterPositions": [
|
|
201
|
+
{
|
|
202
|
+
"character": "CHARACTER NAME",
|
|
203
|
+
"position": "detailed position description",
|
|
204
|
+
"stagePosition": "stage left/right/center, upstage/downstage/center stage",
|
|
205
|
+
"relativePosition": "beside X, behind Y, at Z (optional)",
|
|
206
|
+
"action": "sits/stands/etc (optional)"
|
|
207
|
+
}
|
|
208
|
+
],
|
|
209
|
+
"characterDescriptions": [${needsDescriptions ? `
|
|
210
|
+
{
|
|
211
|
+
"character": "CHARACTER NAME (ONLY NEW CHARACTERS)",
|
|
212
|
+
"physicalAppearance": "detailed physical description (200-800 chars)",
|
|
213
|
+
"wardrobe": "detailed wardrobe description (200-800 chars)",
|
|
214
|
+
"emotion": "emotional state (optional)"
|
|
215
|
+
}` : ' // Empty array - all characters already described'}
|
|
216
|
+
],
|
|
217
|
+
"setDescription": "detailed environment description (400-800 chars)",
|
|
218
|
+
"characterActions": ["movement/action descriptions"],
|
|
219
|
+
"soundEffects": ["sound effect descriptions"]
|
|
220
|
+
}
|
|
221
|
+
\`\`\`
|
|
222
|
+
|
|
223
|
+
Respond with ONLY the JSON object, no additional text.`;
|
|
224
|
+
return prompt;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Parse AI response into structured blocking data
|
|
228
|
+
*/
|
|
229
|
+
parseBlockingResponse(responseText, characterNames) {
|
|
230
|
+
try {
|
|
231
|
+
// Extract JSON from response (may be wrapped in ```json```)
|
|
232
|
+
const jsonMatch = responseText.match(/```json\s*([\s\S]*?)\s*```/) || responseText.match(/({[\s\S]*})/);
|
|
233
|
+
const jsonText = jsonMatch ? jsonMatch[1] : responseText;
|
|
234
|
+
const parsed = JSON.parse(jsonText);
|
|
235
|
+
return {
|
|
236
|
+
characterPositions: parsed.characterPositions || [],
|
|
237
|
+
characterDescriptions: parsed.characterDescriptions || [],
|
|
238
|
+
setDescription: parsed.setDescription || '',
|
|
239
|
+
characterActions: parsed.characterActions || [],
|
|
240
|
+
soundEffects: parsed.soundEffects || []
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
console.error('Failed to parse AI blocking response:', error);
|
|
245
|
+
console.error('Response text:', responseText);
|
|
246
|
+
return {
|
|
247
|
+
characterPositions: [],
|
|
248
|
+
characterDescriptions: [],
|
|
249
|
+
setDescription: '',
|
|
250
|
+
characterActions: [],
|
|
251
|
+
soundEffects: []
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Fallback extraction when AI fails
|
|
257
|
+
*/
|
|
258
|
+
fallbackExtraction(actionLines, characterNames) {
|
|
259
|
+
return {
|
|
260
|
+
characterPositions: characterNames.map(name => ({
|
|
261
|
+
character: name,
|
|
262
|
+
position: 'in scene',
|
|
263
|
+
stagePosition: undefined,
|
|
264
|
+
relativePosition: undefined,
|
|
265
|
+
action: undefined
|
|
266
|
+
})),
|
|
267
|
+
characterDescriptions: [],
|
|
268
|
+
setDescription: actionLines.join('. '),
|
|
269
|
+
characterActions: [],
|
|
270
|
+
soundEffects: []
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
exports.AIBlockingExtractor = AIBlockingExtractor;
|
|
275
|
+
//# sourceMappingURL=ai-blocking-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-blocking-extractor.js","sourceRoot":"","sources":["../../../../src/commands/generate-shot-list/generator/ai-blocking-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI-Powered Entity Extractor
|
|
3
|
+
*
|
|
4
|
+
* Uses AI to intelligently identify characters and objects from Fountain screenplay text
|
|
5
|
+
* following MPAA and AMPAS Nicholl Fellowship screenplay standards.
|
|
6
|
+
*
|
|
7
|
+
* This replaces rigid regex patterns with fuzzy logic that understands:
|
|
8
|
+
* - Character conventions (THE CAPTAIN, FIRST OFFICER, etc.)
|
|
9
|
+
* - Object conventions (airlock door, viewscreen, etc.)
|
|
10
|
+
* - Industry-standard screenplay formatting
|
|
11
|
+
*/
|
|
12
|
+
export interface EntityExtractionResult {
|
|
13
|
+
characters: string[];
|
|
14
|
+
objects: string[];
|
|
15
|
+
confidence: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* AI-powered entity extractor using Claude
|
|
19
|
+
*/
|
|
20
|
+
export declare class AIEntityExtractor {
|
|
21
|
+
private client;
|
|
22
|
+
private apiKey;
|
|
23
|
+
constructor();
|
|
24
|
+
/**
|
|
25
|
+
* Extract characters and objects from screenplay text using AI
|
|
26
|
+
*/
|
|
27
|
+
extractEntities(sceneText: string, sceneHeading: string): Promise<EntityExtractionResult>;
|
|
28
|
+
/**
|
|
29
|
+
* Build prompt for AI entity extraction
|
|
30
|
+
*/
|
|
31
|
+
private buildExtractionPrompt;
|
|
32
|
+
/**
|
|
33
|
+
* Parse AI response into structured result
|
|
34
|
+
*/
|
|
35
|
+
private parseAIResponse;
|
|
36
|
+
/**
|
|
37
|
+
* Fallback regex-based extraction (when AI unavailable)
|
|
38
|
+
*/
|
|
39
|
+
private fallbackExtraction;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=ai-entity-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-entity-extractor.d.ts","sourceRoot":"","sources":["../../../../src/commands/generate-shot-list/generator/ai-entity-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,MAAM,CAAuB;;IAWrC;;OAEG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAmC/F;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAqC7B;;OAEG;IACH,OAAO,CAAC,eAAe;IAwBvB;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAwB3B"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AI-Powered Entity Extractor
|
|
4
|
+
*
|
|
5
|
+
* Uses AI to intelligently identify characters and objects from Fountain screenplay text
|
|
6
|
+
* following MPAA and AMPAS Nicholl Fellowship screenplay standards.
|
|
7
|
+
*
|
|
8
|
+
* This replaces rigid regex patterns with fuzzy logic that understands:
|
|
9
|
+
* - Character conventions (THE CAPTAIN, FIRST OFFICER, etc.)
|
|
10
|
+
* - Object conventions (airlock door, viewscreen, etc.)
|
|
11
|
+
* - Industry-standard screenplay formatting
|
|
12
|
+
*/
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.AIEntityExtractor = void 0;
|
|
18
|
+
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
19
|
+
/**
|
|
20
|
+
* AI-powered entity extractor using Claude
|
|
21
|
+
*/
|
|
22
|
+
class AIEntityExtractor {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.client = null;
|
|
25
|
+
this.apiKey = null;
|
|
26
|
+
// Check for API key in environment
|
|
27
|
+
this.apiKey = process.env.ANTHROPIC_API_KEY || null;
|
|
28
|
+
if (this.apiKey) {
|
|
29
|
+
this.client = new sdk_1.default({ apiKey: this.apiKey });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Extract characters and objects from screenplay text using AI
|
|
34
|
+
*/
|
|
35
|
+
async extractEntities(sceneText, sceneHeading) {
|
|
36
|
+
// Fallback to regex if no API key
|
|
37
|
+
if (!this.client) {
|
|
38
|
+
console.log('No Anthropic API key found, using fallback regex extraction');
|
|
39
|
+
return this.fallbackExtraction(sceneText);
|
|
40
|
+
}
|
|
41
|
+
const prompt = this.buildExtractionPrompt(sceneText, sceneHeading);
|
|
42
|
+
try {
|
|
43
|
+
console.log('Using AI-powered entity extraction...');
|
|
44
|
+
const response = await this.client.messages.create({
|
|
45
|
+
model: 'claude-sonnet-4-6', // Latest Sonnet model (Feb 2026)
|
|
46
|
+
max_tokens: 1024,
|
|
47
|
+
temperature: 0.0, // Deterministic for consistency
|
|
48
|
+
messages: [{
|
|
49
|
+
role: 'user',
|
|
50
|
+
content: prompt
|
|
51
|
+
}]
|
|
52
|
+
});
|
|
53
|
+
const content = response.content[0];
|
|
54
|
+
if (content.type === 'text') {
|
|
55
|
+
const result = this.parseAIResponse(content.text);
|
|
56
|
+
console.log(`AI extracted ${result.characters.length} characters and ${result.objects.length} objects`);
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
return this.fallbackExtraction(sceneText);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
console.warn('AI extraction failed, using fallback:', error);
|
|
63
|
+
return this.fallbackExtraction(sceneText);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Build prompt for AI entity extraction
|
|
68
|
+
*/
|
|
69
|
+
buildExtractionPrompt(sceneText, sceneHeading) {
|
|
70
|
+
return `You are an expert screenplay analyst following MPAA and AMPAS Nicholl Fellowship standards.
|
|
71
|
+
|
|
72
|
+
Extract CHARACTERS and OBJECTS from this Fountain screenplay scene.
|
|
73
|
+
|
|
74
|
+
**SCENE HEADING:**
|
|
75
|
+
${sceneHeading}
|
|
76
|
+
|
|
77
|
+
**SCENE TEXT:**
|
|
78
|
+
${sceneText}
|
|
79
|
+
|
|
80
|
+
**RULES:**
|
|
81
|
+
|
|
82
|
+
**Characters** are people or beings with agency:
|
|
83
|
+
- THE CAPTAIN, FIRST OFFICER, ENGINEER, ENSIGN, ADMIRAL
|
|
84
|
+
- WIZARD CLIF HIGH, HEIDI
|
|
85
|
+
- Any named person or being who speaks or acts
|
|
86
|
+
- Titles used as character names (THE CAPTAIN, not "captain" as description)
|
|
87
|
+
|
|
88
|
+
**Objects** are props, set pieces, or environmental elements:
|
|
89
|
+
- airlock door, viewscreen, console, PADD
|
|
90
|
+
- warp core, transporter, phaser
|
|
91
|
+
- Physical things that characters interact with
|
|
92
|
+
|
|
93
|
+
**Extract ALL CAPS words that are characters or objects.**
|
|
94
|
+
|
|
95
|
+
**OUTPUT FORMAT (JSON only, no explanation):**
|
|
96
|
+
\`\`\`json
|
|
97
|
+
{
|
|
98
|
+
"characters": ["THE CAPTAIN", "FIRST OFFICER", "ENGINEER"],
|
|
99
|
+
"objects": ["airlock door", "viewscreen", "console"]
|
|
100
|
+
}
|
|
101
|
+
\`\`\`
|
|
102
|
+
|
|
103
|
+
Return ONLY the JSON, nothing else.`;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Parse AI response into structured result
|
|
107
|
+
*/
|
|
108
|
+
parseAIResponse(responseText) {
|
|
109
|
+
try {
|
|
110
|
+
// Extract JSON from response (handle markdown code blocks)
|
|
111
|
+
const jsonMatch = responseText.match(/```json\s*([\s\S]*?)\s*```/) ||
|
|
112
|
+
responseText.match(/\{[\s\S]*\}/);
|
|
113
|
+
if (!jsonMatch) {
|
|
114
|
+
throw new Error('No JSON found in response');
|
|
115
|
+
}
|
|
116
|
+
const jsonText = jsonMatch[1] || jsonMatch[0];
|
|
117
|
+
const parsed = JSON.parse(jsonText);
|
|
118
|
+
return {
|
|
119
|
+
characters: parsed.characters || [],
|
|
120
|
+
objects: parsed.objects || [],
|
|
121
|
+
confidence: 0.95 // High confidence for AI extraction
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
console.warn('Failed to parse AI response:', error);
|
|
126
|
+
return { characters: [], objects: [], confidence: 0.0 };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Fallback regex-based extraction (when AI unavailable)
|
|
131
|
+
*/
|
|
132
|
+
fallbackExtraction(sceneText) {
|
|
133
|
+
const characters = [];
|
|
134
|
+
const objects = [];
|
|
135
|
+
// Extract ALL CAPS words (2+ letters)
|
|
136
|
+
const capsRegex = /\b([A-Z]{2,}(?:\s+[A-Z]{2,})*)\b/g;
|
|
137
|
+
const matches = sceneText.matchAll(capsRegex);
|
|
138
|
+
for (const match of matches) {
|
|
139
|
+
const word = match[1].trim();
|
|
140
|
+
// Skip common non-character words
|
|
141
|
+
const skipWords = ['INT', 'EXT', 'DAY', 'NIGHT', 'CONTINUOUS', 'LATER', 'FADE', 'CUT'];
|
|
142
|
+
if (skipWords.includes(word))
|
|
143
|
+
continue;
|
|
144
|
+
// Simple heuristic: if it's a title or name, it's likely a character
|
|
145
|
+
if (word.includes('CAPTAIN') || word.includes('OFFICER') || word.includes('ENGINEER') ||
|
|
146
|
+
word.includes('ENSIGN') || word.includes('ADMIRAL') || word.includes('WIZARD')) {
|
|
147
|
+
if (!characters.includes(word))
|
|
148
|
+
characters.push(word);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return { characters, objects, confidence: 0.5 }; // Lower confidence for fallback
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
exports.AIEntityExtractor = AIEntityExtractor;
|
|
155
|
+
//# sourceMappingURL=ai-entity-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-entity-extractor.js","sourceRoot":"","sources":["../../../../src/commands/generate-shot-list/generator/ai-entity-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { Scene, SceneElement } from '../parser/types';
|
|
13
13
|
import { SceneContext, CharacterState } from './types';
|
|
14
|
+
import { MergedStyleGuidelines } from '../style/types';
|
|
14
15
|
/**
|
|
15
16
|
* Context builder configuration
|
|
16
17
|
*/
|
|
@@ -18,6 +19,7 @@ export interface ContextBuilderConfig {
|
|
|
18
19
|
includeAtmosphere: boolean;
|
|
19
20
|
includeWeather: boolean;
|
|
20
21
|
trackCharacterEmotions: boolean;
|
|
22
|
+
styleGuidelines?: MergedStyleGuidelines | null;
|
|
21
23
|
}
|
|
22
24
|
/**
|
|
23
25
|
* Context Builder class
|
|
@@ -30,7 +32,46 @@ export declare class ContextBuilder {
|
|
|
30
32
|
private characterBlockingHistory;
|
|
31
33
|
private characterBible;
|
|
32
34
|
private setBible;
|
|
35
|
+
private styleGuidelines;
|
|
36
|
+
private aiExtractor;
|
|
33
37
|
constructor(config: ContextBuilderConfig);
|
|
38
|
+
/**
|
|
39
|
+
* Normalize character name for fuzzy matching
|
|
40
|
+
* Handles variations like "THE CAPTAIN" vs "CAPTAIN", "A WIZARD" vs "WIZARD"
|
|
41
|
+
*
|
|
42
|
+
* Rules:
|
|
43
|
+
* - Remove leading articles: THE, A, AN
|
|
44
|
+
* - Trim whitespace
|
|
45
|
+
* - Convert to uppercase for consistent comparison
|
|
46
|
+
*
|
|
47
|
+
* Examples:
|
|
48
|
+
* - "THE CAPTAIN" -> "CAPTAIN"
|
|
49
|
+
* - "A WIZARD" -> "WIZARD"
|
|
50
|
+
* - "AN OFFICER" -> "OFFICER"
|
|
51
|
+
* - "CAPTAIN" -> "CAPTAIN"
|
|
52
|
+
*/
|
|
53
|
+
private normalizeCharacterName;
|
|
54
|
+
/**
|
|
55
|
+
* Find character in Bible using fuzzy matching
|
|
56
|
+
* Tries exact match first, then normalized match, then partial match
|
|
57
|
+
*
|
|
58
|
+
* @param characterName - The character name to search for
|
|
59
|
+
* @returns The Bible entry if found, null otherwise
|
|
60
|
+
*/
|
|
61
|
+
private findCharacterInBible;
|
|
62
|
+
/**
|
|
63
|
+
* Get or create character in Bible using fuzzy matching
|
|
64
|
+
* Returns the canonical name (the one stored in the Bible)
|
|
65
|
+
*
|
|
66
|
+
* @param characterName - The character name to search for
|
|
67
|
+
* @returns Object with bibleEntry and canonicalName
|
|
68
|
+
*/
|
|
69
|
+
private getOrCreateCharacterInBible;
|
|
70
|
+
/**
|
|
71
|
+
* Reset all state (Character Bible, Set Bible, blocking history)
|
|
72
|
+
* Call this at the start of each new screenplay generation to prevent contamination
|
|
73
|
+
*/
|
|
74
|
+
reset(): void;
|
|
34
75
|
/**
|
|
35
76
|
* Build scene-level context from scene heading and elements
|
|
36
77
|
* Requirement 11: Use Set Bible to maintain rich, consistent set descriptions
|
|
@@ -41,9 +82,9 @@ export declare class ContextBuilder {
|
|
|
41
82
|
* Build character states from scene elements
|
|
42
83
|
* Requirement 9: Maintain character blocking continuity across shots
|
|
43
84
|
* Requirement 10: Use Character Bible to maintain rich, consistent character descriptions
|
|
44
|
-
* PRIORITY:
|
|
85
|
+
* PRIORITY: Use AI-powered fuzzy logic to extract characters following MPAA/AMPAS standards
|
|
45
86
|
*/
|
|
46
|
-
buildCharacterStates(elements: SceneElement[], sceneContext: SceneContext): CharacterState[]
|
|
87
|
+
buildCharacterStates(elements: SceneElement[], sceneContext: SceneContext): Promise<CharacterState[]>;
|
|
47
88
|
/**
|
|
48
89
|
* Extract environment description from scene
|
|
49
90
|
* Requirement 11: Rich Set Descriptions
|
|
@@ -72,12 +113,19 @@ export declare class ContextBuilder {
|
|
|
72
113
|
* Extract atmosphere from scene elements
|
|
73
114
|
*/
|
|
74
115
|
private extractAtmosphere;
|
|
116
|
+
/**
|
|
117
|
+
* Check if the scene is set in space (spaceship, space station, etc.)
|
|
118
|
+
* where weather doesn't make sense
|
|
119
|
+
*/
|
|
120
|
+
private isSpaceSetting;
|
|
75
121
|
/**
|
|
76
122
|
* Extract weather from scene elements
|
|
123
|
+
* Style-aware: respects franchise settings (no weather on spaceships!)
|
|
77
124
|
*/
|
|
78
125
|
private extractWeather;
|
|
79
126
|
/**
|
|
80
127
|
* Extract emotion from dialogue element
|
|
128
|
+
* Handles both parenthetical and character extension (V.O., O.S., etc.)
|
|
81
129
|
*/
|
|
82
130
|
private extractEmotion;
|
|
83
131
|
/**
|
|
@@ -99,5 +147,20 @@ export declare class ContextBuilder {
|
|
|
99
147
|
* PRIORITY: Extract actual character descriptions from screenplay
|
|
100
148
|
*/
|
|
101
149
|
private updateCharacterStatesFromAction;
|
|
150
|
+
/**
|
|
151
|
+
* Enrich wardrobe descriptions with specific colors based on cinematic style
|
|
152
|
+
* Maintains visual continuity by adding particular details
|
|
153
|
+
*
|
|
154
|
+
* Star Trek uniform colors:
|
|
155
|
+
* - Command: Gold/Yellow
|
|
156
|
+
* - Science/Medical: Blue
|
|
157
|
+
* - Engineering/Security: Red
|
|
158
|
+
*/
|
|
159
|
+
private enrichWardrobeWithColors;
|
|
160
|
+
/**
|
|
161
|
+
* Extract characters using AI-powered fuzzy logic
|
|
162
|
+
* Follows MPAA and AMPAS Nicholl Fellowship screenplay standards
|
|
163
|
+
*/
|
|
164
|
+
private extractCharactersWithAI;
|
|
102
165
|
}
|
|
103
166
|
//# sourceMappingURL=context-builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-builder.d.ts","sourceRoot":"","sources":["../../../../src/commands/generate-shot-list/generator/context-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAE,YAAY,EAAkC,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"context-builder.d.ts","sourceRoot":"","sources":["../../../../src/commands/generate-shot-list/generator/context-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAE,YAAY,EAAkC,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAGvD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,sBAAsB,EAAE,OAAO,CAAC;IAChC,eAAe,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;CAChD;AAkCD;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,wBAAwB,CAA0C;IAC1E,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,QAAQ,CAAyC;IACzD,OAAO,CAAC,eAAe,CAAsC;IAC7D,OAAO,CAAC,WAAW,CAAoB;gBAE3B,MAAM,EAAE,oBAAoB;IAMxC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,sBAAsB;IAO9B;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IAuB5B;;;;;;OAMG;IACH,OAAO,CAAC,2BAA2B;IAuBnC;;;OAGG;IACH,KAAK,IAAI,IAAI;IAOb;;;;OAIG;IACH,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,YAAY;IA+D7C;;;;;OAKG;IACG,oBAAoB,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAqK3G;;;OAGG;IACH;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAyBnC,OAAO,CAAC,kBAAkB;IA8B1B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAyD3B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAsB1B;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAsBzB;;;OAGG;IACH,OAAO,CAAC,cAAc;IA2BtB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAqBtB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAyCtB;;;;;OAKG;IACH,OAAO,CAAC,uCAAuC;IAkF/C;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IAqCpC;;;;;OAKG;IACH,OAAO,CAAC,+BAA+B;IA2KvC;;;;;;;;OAQG;IACH,OAAO,CAAC,wBAAwB;IAkEhC;;;OAGG;YACW,uBAAuB;CAuCtC"}
|