@bernierllc/content-workflow-ai-review-step
v0.3.0
Published
AI-powered content review workflow step with grammar, SEO, tone, and engagement analysis
Readme
@bernierllc/content-workflow-ai-review-step
AI-powered content review workflow step with comprehensive analysis for grammar, SEO, tone, engagement, and readability.
Features
- Multi-Provider Support: Works with OpenAI GPT-4 and Anthropic Claude via AI Provider Router
- Comprehensive Analysis: Grammar, SEO optimization, tone consistency, engagement potential, and readability
- Structured Suggestions: Location-aware suggestions with severity levels (critical, warning, suggestion)
- Scoring System: Overall score (0-100) plus category-specific scores
- Custom Prompts: Configurable review prompts per workflow
- Cost Tracking: Token usage and cost tracking per review
- Event Publishing: Optional NeverHub integration for real-time progress updates
- Type-Safe: Full TypeScript support with strict mode
Installation
npm install @bernierllc/content-workflow-ai-review-stepQuick Start
import { AIReviewStep } from '@bernierllc/content-workflow-ai-review-step';
import { AIProviderRouter } from '@bernierllc/ai-provider-router';
import { Logger } from '@bernierllc/logger';
// Initialize dependencies
const aiRouter = new AIProviderRouter({
providers: [
{
name: 'openai',
priority: 1,
enabled: true,
},
],
});
const logger = new Logger({ level: 'info' });
// Create review step
const reviewStep = new AIReviewStep(aiRouter, logger);
// Execute review
const result = await reviewStep.execute(
{
id: 'review-step-1',
name: 'AI Review',
type: 'ai_review',
enabled: true,
order: 0,
aiConfig: {
provider: 'openai',
model: 'gpt-4',
temperature: 0.3,
},
},
{
content: {
id: 'article-123',
title: 'How to Write Great Content',
body: 'This is the article body...',
},
}
);
if (result.success && result.data) {
console.log('Overall Score:', result.data.overallScore);
console.log('Suggestions:', result.data.suggestions.length);
console.log('Summary:', result.data.summary);
}Configuration
Step Configuration
interface WorkflowStepConfig {
id: string; // Unique step identifier
name: string; // Step display name
type: 'ai_review'; // Must be 'ai_review'
enabled: boolean; // Whether step is active
order: number; // Execution order
aiConfig?: {
provider?: string; // 'openai', 'anthropic', or 'auto'
model?: string; // Specific model (e.g., 'gpt-4')
prompt?: string; // Custom review prompt
temperature?: number; // 0-1, default 0.3
maxTokens?: number; // 100-10000, default 2000
};
}Content Context
interface WorkflowContext {
content: {
id: string;
title?: string;
body: string;
metadata?: Record<string, unknown>;
};
userId?: string;
metadata?: Record<string, unknown>;
}Review Result Structure
interface AIReviewResult {
// Overall quality score (0-100)
overallScore: number;
// Category scores
scores: {
grammar: number; // 0-100
seo: number; // 0-100
tone: number; // 0-100
engagement: number; // 0-100
readability: number; // 0-100
};
// Actionable suggestions
suggestions: AIReviewSuggestion[];
// Summary of review
summary: string;
// Provider metadata
provider: string; // 'openai', 'anthropic'
model: string; // Model used
tokensUsed: number; // Tokens consumed
costUsd: number; // Estimated cost
}Suggestion Format
interface AIReviewSuggestion {
type: 'grammar' | 'seo' | 'tone' | 'engagement' | 'readability' | 'clarity';
severity: 'critical' | 'warning' | 'suggestion';
// Original problematic text
original: string;
// Suggested improvement
suggestion: string;
// Explanation
reason: string;
// Location (optional)
location?: {
line?: number;
column?: number;
offset?: number;
length?: number;
};
// User acceptance (optional)
accepted?: boolean;
}Advanced Usage
Custom Review Prompts
const result = await reviewStep.execute(
{
id: 'custom-review',
name: 'Technical Blog Review',
type: 'ai_review',
enabled: true,
order: 0,
aiConfig: {
provider: 'openai',
prompt: `Review this technical blog post for:
1. Technical accuracy
2. Code example quality
3. Developer-friendly tone
4. SEO optimization for technical keywords
Provide specific, actionable feedback.`,
},
},
context
);With NeverHub Events
import { NeverHubAdapter } from '@bernierllc/neverhub-adapter';
const neverhub = new NeverHubAdapter();
await neverhub.register({
type: 'content-workflow',
capabilities: ['ai-review'],
});
const reviewStep = new AIReviewStep(aiRouter, logger, neverhub);
// Events published:
// - ai.review.started
// - ai.review.completed
// - ai.review.failedValidation
const validation = reviewStep.validate(config);
if (!validation.valid) {
console.error('Config errors:', validation.errors);
}Utility Functions
Prompt Building
import {
buildReviewPrompt,
buildQuickReviewPrompt,
estimateTokenCount
} from '@bernierllc/content-workflow-ai-review-step';
const prompt = buildReviewPrompt(content);
const quickPrompt = buildQuickReviewPrompt(content, ['grammar', 'clarity']);
const tokenEstimate = estimateTokenCount(prompt);Scoring Utilities
import {
calculateOverallScore,
getQualityLevel,
getWeakestCategory,
compareScores,
} from '@bernierllc/content-workflow-ai-review-step';
const overall = calculateOverallScore(scores);
const quality = getQualityLevel(overall);
const weakness = getWeakestCategory(scores);
const improvement = compareScores(oldScores, newScores);Response Parsing
import {
parseReviewResponse,
validateReviewResult
} from '@bernierllc/content-workflow-ai-review-step';
const result = parseReviewResponse(
aiResponse,
'openai',
'gpt-4',
500,
0.01
);
const validation = validateReviewResult(result);Error Handling
const result = await reviewStep.execute(config, context);
if (!result.success) {
console.error('Review failed:', result.error);
// Check metadata for partial info
if (result.metadata?.durationMs) {
console.log('Failed after', result.metadata.durationMs, 'ms');
}
}Performance Considerations
- Token Usage: Default maxTokens is 2000. Adjust based on content length.
- Temperature: Lower temperature (0.2-0.4) provides more consistent reviews.
- Provider Selection: Use 'auto' for automatic provider selection with failover.
- Caching: Results are NOT cached by default. Implement your own caching if needed.
Testing
# Run tests
npm test
# Run with coverage
npm run test:coverage
# Run without watch mode
npm run test:runRequirements
- Dependencies:
@bernierllc/ai-provider-router- AI provider routing@bernierllc/logger- Logging@bernierllc/neverhub-adapter(optional) - Event publishing
- Environment:
- Node.js 18+
- TypeScript 5.3+
License
Copyright (c) 2025 Bernier LLC
This file is licensed to the client under a limited-use license. The client may use and modify this code only within the scope of the project it was delivered for. Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
Related Packages
- @bernierllc/ai-provider-router - AI provider selection and routing
- @bernierllc/ai-content-reviewer - Content review logic
- @bernierllc/content-editorial-workflow - Workflow state machine
- @bernierllc/content-workflow-step-manager - Step orchestration
Support
For issues and questions, please contact Bernier LLC.
