story-weaver-ai
Version:
A narrative development system for AI-driven storytelling with Jungian psychology
188 lines (167 loc) • 7.17 kB
JavaScript
/**
* Story Analysis Module
*
* @author Sean Pavlak
* @github https://github.com/seanpavlak/cursor-story-master
*
* A module for analyzing and refining stories using AI.
* This provides functionality for detailed plot analysis and story refinement.
*/
import { log } from './utils.js';
import { Anthropic } from '@anthropic-ai/sdk';
import dotenv from 'dotenv';
import chalk from 'chalk';
import { startLoadingIndicator, stopLoadingIndicator } from './ui.js';
// Load environment variables
dotenv.config();
// Configure Anthropic client
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
defaultHeaders: {
'anthropic-beta': 'output-128k-2025-02-19'
}
});
/**
* Analyze a story's plot structure and narrative elements
* @param {string} storyContent - The story content to analyze
* @param {Object} options - Analysis options
* @param {boolean} options.deepAnalysis - Whether to perform deep psychological analysis
* @param {boolean} options.includeRecommendations - Whether to include improvement recommendations
* @returns {Object} Analysis results
*/
export async function analyzePlot(storyContent, options = {}) {
const { deepAnalysis = false, includeRecommendations = true } = options;
log('info', 'Analyzing story plot structure...');
const loadingIndicator = startLoadingIndicator('Analyzing plot structure...');
try {
const systemPrompt = `You are a literary analysis expert specializing in narrative structure, character development, and story coherence.
Analyze the provided story content with focus on:
1. Plot Structure: Identify the story's structure (three-act, hero's journey, etc.) and analyze its effectiveness
2. Character Development: Evaluate character arcs, motivations, and consistency
3. Pacing and Flow: Assess narrative pacing, transitions, and scene structure
4. Thematic Elements: Identify themes, motifs, and symbols
5. Narrative Coherence: Evaluate the overall story coherence and logical progression
${deepAnalysis ? '6. Psychological Depth: Analyze the psychological underpinnings using Jungian principles' : ''}
${includeRecommendations ? '7. Improvement Recommendations: Suggest specific, actionable ways to strengthen the story' : ''}
Provide a comprehensive analysis in JSON format:
{
"structure": {
"type": "string",
"effectiveness": 1-10,
"analysis": "string"
},
"characters": [
{
"name": "string",
"arc": "string",
"strengths": ["string"],
"weaknesses": ["string"],
"analysis": "string"
}
],
"pacing": {
"rating": 1-10,
"strongSequences": ["string"],
"weakSequences": ["string"],
"analysis": "string"
},
"themes": {
"primary": ["string"],
"secondary": ["string"],
"analysis": "string"
},
"coherence": {
"rating": 1-10,
"analysis": "string"
}${deepAnalysis ? ',\n "psychologicalAnalysis": {\n "archetypes": ["string"],\n "symbols": ["string"],\n "unconsciousElements": ["string"],\n "analysis": "string"\n }' : ''}${includeRecommendations ? ',\n "recommendations": [\n {\n "area": "string",\n "issue": "string",\n "recommendation": "string",\n "priority": "high|medium|low"\n }\n ]' : ''}
}`;
const response = await anthropic.messages.create({
model: "claude-3-7-sonnet-20240620",
max_tokens: 100000,
temperature: 0.2,
system: systemPrompt,
messages: [
{
role: 'user',
content: `Here is the story to analyze:\n\n${storyContent}`
}
]
});
stopLoadingIndicator(loadingIndicator);
// Parse the response JSON
try {
return JSON.parse(response.content[0].text);
} catch (error) {
log('error', 'Failed to parse analysis results as JSON');
return {
error: 'Failed to parse analysis results',
rawContent: response.content[0].text
};
}
} catch (error) {
stopLoadingIndicator(loadingIndicator);
log('error', `Error analyzing plot: ${error.message}`);
throw new Error(`Failed to analyze plot: ${error.message}`);
}
}
/**
* Refine a story based on analysis and user preferences
* @param {string} storyContent - The original story content
* @param {Object} analysis - Analysis results from analyzePlot
* @param {Object} refinementOptions - Refinement options
* @param {string[]} refinementOptions.focusAreas - Areas to focus on (e.g., "pacing", "characters")
* @param {string} refinementOptions.toneAdjustment - Desired tone adjustment (e.g., "darker", "lighter")
* @param {string} refinementOptions.additionalGuidance - Any additional refinement guidance
* @returns {string} The refined story content
*/
export async function refineStory(storyContent, analysis, refinementOptions = {}) {
const {
focusAreas = [],
toneAdjustment = "preserve",
additionalGuidance = ""
} = refinementOptions;
log('info', 'Refining story based on analysis...');
const loadingIndicator = startLoadingIndicator('Refining story...');
try {
// Convert analysis to string if it's an object
const analysisStr = typeof analysis === 'object' ? JSON.stringify(analysis, null, 2) : analysis;
// Build focus areas string
const focusAreasStr = focusAreas.length > 0
? `Focus particularly on improving these areas: ${focusAreas.join(', ')}.`
: 'Focus on improving the most critical areas based on the analysis.';
// Build tone adjustment string
let toneStr = '';
if (toneAdjustment !== 'preserve') {
toneStr = `Adjust the tone to be ${toneAdjustment} while maintaining the story's essence.`;
} else {
toneStr = 'Preserve the original tone of the story.';
}
const systemPrompt = `You are a professional editor and story consultant specializing in narrative refinement and storytelling excellence.
Your task is to refine the provided story based on the accompanying analysis and specific refinement requests.
Guidelines for refinement:
1. Preserve the core story elements and author's voice
2. Make targeted improvements to strengthen the narrative
3. ${focusAreasStr}
4. ${toneStr}
5. ${additionalGuidance ? additionalGuidance : 'Ensure the refinements enhance the story without changing its fundamental nature.'}
Return the complete refined story text. Do not include explanatory notes or commentary within the story itself.`;
const response = await anthropic.messages.create({
model: "claude-3-7-sonnet-20240620",
max_tokens: 100000,
temperature: 0.3,
system: systemPrompt,
messages: [
{
role: 'user',
content: `Here is the original story:\n\n${storyContent}\n\nHere is the analysis of the story:\n\n${analysisStr}\n\nPlease refine the story based on this analysis and the specified refinement options.`
}
]
});
stopLoadingIndicator(loadingIndicator);
return response.content[0].text;
} catch (error) {
stopLoadingIndicator(loadingIndicator);
log('error', `Error refining story: ${error.message}`);
throw new Error(`Failed to refine story: ${error.message}`);
}
}