@bernierllc/ai-response-parser
v1.0.1
Published
Parse and validate AI model responses with JSON extraction, markdown parsing, and schema validation
Readme
@bernierllc/ai-response-parser
Parse and validate AI model responses with JSON extraction, markdown parsing, and schema validation.
Installation
npm install @bernierllc/ai-response-parserFeatures
- JSON Extraction: Extract JSON from AI responses in various formats (code blocks, inline, etc.)
- Markdown Parsing: Extract and sanitize markdown content
- Schema Validation: Validate extracted data against JSON schemas
- Multiple Provider Support: Handle responses from different AI providers
- Error Handling: Graceful handling of malformed responses
- Security: Built-in sanitization to prevent XSS attacks
- TypeScript: Full type safety with strict mode
Usage
Basic JSON Parsing
import { AIResponseParser } from '@bernierllc/ai-response-parser';
const parser = new AIResponseParser();
// Parse JSON from AI response
const response = `
Here is the analysis result:
\`\`\`json
{
"score": 95,
"passed": true,
"feedback": "Excellent work!"
}
\`\`\`
`;
const data = parser.parseJSON<{ score: number; passed: boolean; feedback: string }>(response);
if (data) {
console.log(`Score: ${data.score}`);
console.log(`Passed: ${data.passed}`);
console.log(`Feedback: ${data.feedback}`);
}JSON Extraction with Metadata
const extracted = parser.extractJSON(response);
if (extracted.success) {
console.log('Data:', extracted.data);
console.log('Raw JSON:', extracted.raw);
} else {
console.error('Error:', extracted.error);
}Markdown Extraction
const markdown = parser.extractMarkdown(`
# Analysis Report
This is the **main content** with some formatting.
\`\`\`typescript
const example = "code";
\`\`\`
More text here.
`);
console.log('Content:', markdown.content);
console.log('Has markdown:', markdown.hasMarkdown);
console.log('Code blocks:', markdown.codeBlocks.length);
markdown.codeBlocks.forEach(block => {
console.log(`Language: ${block.language}`);
console.log(`Code: ${block.code}`);
console.log(`Lines: ${block.startLine}-${block.endLine}`);
});Schema Validation
import { JSONSchema } from '@bernierllc/ai-response-parser';
const schema: JSONSchema = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
age: { type: 'number', minimum: 0, maximum: 150 },
email: {
type: 'string',
pattern: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'
}
},
required: ['name', 'email'],
additionalProperties: false
};
const response = `
\`\`\`json
{
"name": "John Doe",
"age": 30,
"email": "[email protected]"
}
\`\`\`
`;
const result = parser.validate(response, schema);
if (result.valid) {
console.log('Valid data:', result.data);
} else {
console.error('Validation errors:');
result.errors?.forEach(error => {
console.error(`${error.path}: ${error.message}`);
if (error.expected) console.error(`Expected: ${error.expected}`);
if (error.received) console.error(`Received: ${error.received}`);
});
}Complete Parsing
const parseResult = parser.parse(response);
if (parseResult.success) {
console.log('JSON data:', parseResult.data);
}
if (parseResult.markdown) {
console.log('Markdown content:', parseResult.markdown.content);
console.log('Code blocks:', parseResult.markdown.codeBlocks);
}
if (parseResult.errors) {
console.error('Errors:', parseResult.errors);
}Configuration
const parser = new AIResponseParser({
// Enable strict JSON parsing (default: true)
strictJSON: true,
// Maximum depth for nested objects (default: 10)
maxDepth: 10,
// Enable markdown sanitization (default: true)
sanitizeMarkdown: true,
// Custom JSON extraction patterns
jsonPatterns: [
/```json\s*([\s\S]*?)\s*```/g,
/```\s*([\s\S]*?)\s*```/g,
/\{[\s\S]*\}/g,
/\[[\s\S]*\]/g
]
});API Reference
AIResponseParser
Main parser class for handling AI responses.
Constructor
constructor(config?: ParserConfig)Methods
parseJSON<T>(response: string): T | null
Parse JSON from response, returning typed data or null if parsing fails.
extractJSON<T>(response: string): ExtractedJSON<T>
Extract JSON with detailed success/error information.
Returns:
interface ExtractedJSON<T> {
success: boolean;
data?: T;
raw?: string;
error?: string;
}extractMarkdown(response: string): ExtractedMarkdown
Extract markdown content and code blocks.
Returns:
interface ExtractedMarkdown {
content: string;
codeBlocks: CodeBlock[];
hasMarkdown: boolean;
}validate<T>(response: string, schema: JSONSchema): ValidationResult<T>
Validate response against JSON schema.
Returns:
interface ValidationResult<T> {
valid: boolean;
data?: T;
errors?: ValidationError[];
}parse<T>(response: string): ParseResult<T>
Complete parsing with both JSON and markdown extraction.
Returns:
interface ParseResult<T> {
success: boolean;
data?: T;
markdown?: ExtractedMarkdown;
errors?: string[];
}JSON Schema Support
The parser supports a subset of JSON Schema for validation:
- Types: object, array, string, number, boolean, null
- Object: properties, required, additionalProperties
- Array: items, minItems, maxItems
- String: pattern, minLength, maxLength, enum
- Number: minimum, maximum, enum
Example:
const schema: JSONSchema = {
type: 'object',
properties: {
status: {
type: 'string',
enum: ['pending', 'active', 'completed']
},
items: {
type: 'array',
items: { type: 'string' },
minItems: 1,
maxItems: 10
},
metadata: {
type: 'object',
properties: {
createdAt: { type: 'string' },
score: { type: 'number', minimum: 0, maximum: 100 }
},
required: ['createdAt']
}
},
required: ['status', 'items']
};Security
The parser includes built-in security features:
- HTML Sanitization: Removes
<script>,<iframe>, and event handlers - Depth Limiting: Prevents stack overflow from deeply nested objects
- Pattern Validation: Validates string patterns for common formats
To disable sanitization (not recommended):
const parser = new AIResponseParser({ sanitizeMarkdown: false });Error Handling
All parsing methods handle errors gracefully:
// parseJSON returns null on error
const data = parser.parseJSON(response);
if (!data) {
console.error('Failed to parse JSON');
}
// extractJSON provides detailed error information
const extracted = parser.extractJSON(response);
if (!extracted.success) {
console.error('Error:', extracted.error);
}
// validate provides validation errors
const validation = parser.validate(response, schema);
if (!validation.valid) {
validation.errors?.forEach(err => {
console.error(`${err.path}: ${err.message}`);
});
}Integration Status
Logger Integration
Status: Integrated
Justification: This package uses @bernierllc/logger for structured logging of parsing operations. Logs include parsing errors, validation failures, and performance metrics to help with debugging and monitoring AI response processing.
Pattern: Direct integration - logger is a required dependency for this package.
NeverHub Integration
Status: Not applicable
Justification: This is a core utility package that performs AI response parsing. It does not participate in service discovery, event publishing, or service mesh operations. Response parsing is a stateless utility operation that doesn't require service registration or discovery.
Pattern: Core utility - no service mesh integration needed.
Docs-Suite Integration
Status: Ready
Format: TypeDoc-compatible JSDoc comments are included throughout the source code. All public APIs are documented with examples and type information.
Common Patterns
Parsing AI Content Review Responses
interface ReviewResult {
grammarScore: number;
readabilityScore: number;
suggestions: string[];
approved: boolean;
}
const response = await aiService.review(content);
const result = parser.parseJSON<ReviewResult>(response);
if (result && result.approved) {
console.log('Content approved!');
console.log('Grammar:', result.grammarScore);
console.log('Readability:', result.readabilityScore);
}Parsing Social Media Generation Responses
interface SocialPost {
platform: 'twitter' | 'linkedin' | 'instagram';
content: string;
hashtags: string[];
scheduledTime?: string;
}
const aiResponse = await aiService.generatePost(prompt);
const posts = parser.parseJSON<SocialPost[]>(aiResponse);
if (posts) {
for (const post of posts) {
await publishToSocialMedia(post);
}
}Handling Mixed Content Responses
const response = `
Based on my analysis:
## Summary
The content is well-written.
## Data
\`\`\`json
{
"score": 92,
"issues": ["Minor typo in paragraph 3"]
}
\`\`\`
## Recommendations
1. Fix the typo
2. Consider adding examples
`;
const result = parser.parse(response);
// Access JSON data
console.log('Score:', result.data?.score);
// Access markdown content
console.log('Summary:', result.markdown?.content);Testing
The package includes comprehensive tests with 90%+ coverage:
# Run tests
npm test
# Run tests with coverage
npm run test:coverage
# Run tests once
npm run test:runLicense
Copyright (c) 2025 Bernier LLC. All rights reserved.
See Also
- @bernierllc/logger - Logging utilities
- @bernierllc/ai-content-reviewer - AI content review service
- @bernierllc/ai-social-generator - AI social media generation
