/**
* Formats content for optimal LLM consumption with structured prompts
*/
export default class PromptFormatter {
constructor(options = {}) {
this.config = {
defaultFormat: options.defaultFormat || 'structured',
includeMetadata: options.includeMetadata !== false,
includeInstructions: options.includeInstructions !== false,
preserveStructure: options.preserveStructure !== false,
contextMarkers: options.contextMarkers !== false,
debugMode: options.debugMode || false,
...options
};
this.initializeFormats();
this.initializeTemplates();
this.initializeInstructions();
}
/**
* Initialize available output formats
*/
initializeFormats() {
this.formats = {
json: {
name: 'JSON Format',
handler: this.formatAsJSON.bind(this),
description: 'Structured JSON output for programmatic consumption',
useCases: ['API responses', 'data processing', 'structured analysis']
},
markdown: {
name: 'Markdown Format',
handler: this.formatAsMarkdown.bind(this),
description: 'Human-readable markdown with structure preservation',
useCases: ['documentation', 'reports', 'readable output']
},
structured: {
name: 'Structured Prompt Format',
handler: this.formatAsStructured.bind(this),
description: 'LLM-optimized format with clear sections and context',
useCases: ['LLM prompts', 'conversation', 'reasoning tasks']
},
conversational: {
name: 'Conversational Format',
handler: this.formatAsConversational.bind(this),
description: 'Natural language format for chat interfaces',
useCases: ['chat responses', 'summaries', 'explanations']
},
analytical: {
name: 'Analytical Format',
handler: this.formatAsAnalytical.bind(this),
description: 'Detailed analysis format with insights and patterns',
useCases: ['research', 'analysis', 'insights generation']
}
};
}
/**
* Initialize formatting templates
*/
initializeTemplates() {
this.templates = {
structured: {
header: '# ZPT Navigation Results\n\n',
navigation: '## Navigation Context\n**Zoom:** {zoom}\n**Pan:** {pan}\n**Tilt:** {tilt}\n\n',
content: '## Content\n\n{content}\n\n',
metadata: '## Metadata\n{metadata}\n\n',
footer: '---\n*Generated by ZPT Navigation System*'
},
analytical: {
header: '# Analysis Report\n\n',
summary: '## Executive Summary\n{summary}\n\n',
findings: '## Key Findings\n{findings}\n\n',
details: '## Detailed Analysis\n{details}\n\n',
patterns: '## Patterns & Insights\n{patterns}\n\n',
metadata: '## Analysis Metadata\n{metadata}\n\n'
},
conversational: {
greeting: 'Based on your navigation through the corpus using zoom level "{zoom}", here\'s what I found:\n\n',
content: '{content}\n\n',
context: 'This analysis was generated using {tilt} representation{filters}.\n\n',
closing: 'Would you like to explore further or adjust the navigation parameters?'
}
};
}
/**
* Initialize instruction sets for different use cases
*/
initializeInstructions() {
this.instructions = {
analysis: {
prefix: 'Please analyze the following content extracted from a knowledge corpus:',
context: 'The content was selected using specific navigation parameters (zoom/pan/tilt) to focus on relevant information.',
guidance: 'Pay attention to patterns, relationships, and key insights. Consider the navigation context when interpreting the results.',
suffix: 'Provide a comprehensive analysis considering both the content and the navigation methodology used.'
},
summarization: {
prefix: 'Please summarize the following corpus content:',
context: 'This content represents a focused view of a larger knowledge corpus, filtered by specific criteria.',
guidance: 'Create a concise summary that captures the essential information while maintaining context.',
suffix: 'Focus on the most important points and their relationships.'
},
question_answering: {
prefix: 'Use the following corpus content to answer questions:',
context: 'The content has been specifically selected and filtered to be relevant to potential queries.',
guidance: 'Base your answers strictly on the provided content. If information is not available, indicate this clearly.',
suffix: 'Provide accurate, evidence-based responses citing the relevant sections.'
},
exploration: {
prefix: 'Explore and explain the following content from a knowledge corpus:',
context: 'This content represents a specific perspective through the corpus based on navigation parameters.',
guidance: 'Identify interesting patterns, connections, and insights. Consider multiple viewpoints.',
suffix: 'Highlight discoveries and suggest areas for further exploration.'
}
};
}
/**
* Main formatting method - transforms projected content for LLM consumption
* @param {Object} projectedContent - Content from TiltProjector
* @param {Object} navigationContext - ZPT navigation context
* @param {Object} options - Formatting options
* @returns {Object} Formatted content ready for LLM
*/
async format(projectedContent, navigationContext, options = {}) {
const startTime = Date.now();
const opts = { ...this.config, ...options };
try {
// Determine output format
const format = opts.format || this.config.defaultFormat;
const formatter = this.formats[format];
if (!formatter) {
throw new Error(`Unknown format: ${format}`);
}
// Prepare formatting context
const formattingContext = this.buildFormattingContext(
projectedContent,
navigationContext,
opts
);
// Apply format-specific transformation
const formattedContent = await formatter.handler(formattingContext, opts);
// Add instructions if requested
const instructionalContent = this.addInstructions(formattedContent, opts);
// Add metadata markers if requested
const finalContent = this.addContextMarkers(instructionalContent, formattingContext, opts);
const result = {
content: finalContent,
format,
metadata: {
originalProjection: projectedContent.representation,
outputFormat: format,
hasInstructions: opts.includeInstructions,
hasMetadata: opts.includeMetadata,
processingTime: Date.now() - startTime,
tokenEstimate: this.estimateTokenCount(finalContent)
},
context: formattingContext
};
return result;
} catch (error) {
throw new Error(`Formatting failed: ${error.message}`);
}
}
/**
* Build comprehensive formatting context
*/
buildFormattingContext(projectedContent, navigationContext, options) {
const { representation, data, metadata } = projectedContent;
const { zoom, pan, tilt } = navigationContext;
return {
// Core content
projection: {
type: representation,
data,
metadata
},
// Navigation context
navigation: {
zoom,
pan,
tilt,
hasFilters: Object.keys(pan || {}).length > 0,
filterSummary: this.summarizeFilters(pan)
},
// Content analysis
analysis: {
contentType: this.analyzeContentType(data),
complexity: this.assessComplexity(data),
structure: this.analyzeStructure(data),
insights: this.extractInsights(data, representation)
},
// Formatting context
formatting: {
timestamp: new Date().toISOString(),
options,
purpose: options.purpose || 'general'
}
};
}
/**
* Format as JSON
*/
async formatAsJSON(context, options) {
const { projection, navigation, analysis } = context;
const jsonOutput = {
zpt_navigation: {
zoom: navigation.zoom,
pan: navigation.pan,
tilt: navigation.tilt
},
content: {
type: projection.type,
data: projection.data,
analysis: options.includeAnalysis ? analysis : undefined
},
metadata: options.includeMetadata ? {
projection_metadata: projection.metadata,
content_analysis: analysis,
formatting: context.formatting
} : undefined
};
// Clean undefined values
return JSON.stringify(jsonOutput, (key, value) => value === undefined ? null : value, 2);
}
/**
* Format as Markdown
*/
async formatAsMarkdown(context, options) {
const { projection, navigation, analysis } = context;
let markdown = '';
// Header
markdown += `# Corpus Navigation Results\n\n`;
// Navigation context
markdown += `## Navigation Parameters\n\n`;
markdown += `- **Zoom Level:** ${navigation.zoom}\n`;
markdown += `- **Tilt Representation:** ${navigation.tilt}\n`;
if (navigation.hasFilters) {
markdown += `- **Applied Filters:** ${navigation.filterSummary}\n`;
}
markdown += `\n`;
// Content section
markdown += `## Content\n\n`;
markdown += this.formatContentAsMarkdown(projection.data, projection.type);
// Analysis section
if (options.includeAnalysis && analysis) {
markdown += `\n## Analysis\n\n`;
markdown += this.formatAnalysisAsMarkdown(analysis);
}
// Metadata section
if (options.includeMetadata) {
markdown += `\n## Metadata\n\n`;
markdown += this.formatMetadataAsMarkdown(projection.metadata, context.formatting);
}
return markdown;
}
/**
* Format as structured prompt
*/
async formatAsStructured(context, options) {
const { projection, navigation, analysis } = context;
const template = this.templates.structured;
let structured = '';
// Header
structured += template.header;
// Navigation context
const panDescription = navigation.hasFilters ?
` with filters: ${navigation.filterSummary}` : '';
structured += template.navigation
.replace('{zoom}', navigation.zoom)
.replace('{pan}', panDescription)
.replace('{tilt}', navigation.tilt);
// Content
const formattedContent = this.formatContentForLLM(projection.data, projection.type, options);
structured += template.content.replace('{content}', formattedContent);
// Metadata
if (options.includeMetadata) {
const metadataText = this.formatMetadataForLLM(projection.metadata, analysis);
structured += template.metadata.replace('{metadata}', metadataText);
}
// Footer
structured += template.footer;
return structured;
}
/**
* Format as conversational
*/
async formatAsConversational(context, options) {
const { projection, navigation, analysis } = context;
const template = this.templates.conversational;
let conversational = '';
// Greeting with context
conversational += template.greeting.replace('{zoom}', navigation.zoom);
// Content in natural language
const naturalContent = this.formatContentNaturally(projection.data, projection.type);
conversational += template.content.replace('{content}', naturalContent);
// Context explanation
const filterText = navigation.hasFilters ?
` and filtered by ${navigation.filterSummary}` : '';
conversational += template.context
.replace('{tilt}', navigation.tilt)
.replace('{filters}', filterText);
// Closing
conversational += template.closing;
return conversational;
}
/**
* Format as analytical
*/
async formatAsAnalytical(context, options) {
const { projection, navigation, analysis } = context;
const template = this.templates.analytical;
let analytical = '';
// Header
analytical += template.header;
// Executive summary
const summary = this.generateExecutiveSummary(projection.data, navigation, analysis);
analytical += template.summary.replace('{summary}', summary);
// Key findings
const findings = this.extractKeyFindings(projection.data, projection.type, analysis);
analytical += template.findings.replace('{findings}', findings);
// Detailed analysis
const details = this.formatDetailedAnalysis(projection.data, projection.type);
analytical += template.details.replace('{details}', details);
// Patterns and insights
const patterns = this.identifyPatterns(projection.data, analysis);
analytical += template.patterns.replace('{patterns}', patterns);
// Metadata
if (options.includeMetadata) {
const metadata = this.formatAnalyticalMetadata(projection.metadata, context.formatting);
analytical += template.metadata.replace('{metadata}', metadata);
}
return analytical;
}
/**
* Content formatting helpers
*/
formatContentAsMarkdown(data, type) {
switch (type) {
case 'vector':
return this.formatEmbeddingsAsMarkdown(data);
case 'text':
return this.formatKeywordsAsMarkdown(data);
case 'structured':
return this.formatGraphAsMarkdown(data);
case 'sequence':
return this.formatTemporalAsMarkdown(data);
default:
return `\`\`\`json\n${JSON.stringify(data, null, 2)}\n\`\`\``;
}
}
formatEmbeddingsAsMarkdown(data) {
const { embeddings, aggregateStats, centroid } = data;
let markdown = `### Embedding Analysis\n\n`;
markdown += `- **Total embeddings:** ${embeddings.length}\n`;
markdown += `- **Average similarity:** ${aggregateStats.avgSimilarity.toFixed(3)}\n`;
markdown += `- **Dimension:** ${aggregateStats.dimension}\n`;
markdown += `- **Model:** ${aggregateStats.model}\n\n`;
if (embeddings.length > 0) {
markdown += `#### Top Similar Items\n\n`;
const topItems = embeddings
.sort((a, b) => b.similarity - a.similarity)
.slice(0, 5);
topItems.forEach((item, index) => {
markdown += `${index + 1}. **Similarity:** ${item.similarity.toFixed(3)} - ${item.uri}\n`;
});
}
return markdown;
}
formatKeywordsAsMarkdown(data) {
const { globalKeywords, summary, stats } = data;
let markdown = `### Keyword Analysis\n\n`;
markdown += `**Summary:** ${summary}\n\n`;
markdown += `- **Total unique keywords:** ${stats.totalKeywords}\n`;
markdown += `- **Average keywords per item:** ${stats.avgKeywordsPerCorpuscle.toFixed(1)}\n`;
markdown += `- **Coverage score:** ${stats.coverageScore.toFixed(3)}\n\n`;
if (globalKeywords.length > 0) {
markdown += `#### Top Keywords\n\n`;
globalKeywords.slice(0, 10).forEach((kw, index) => {
markdown += `${index + 1}. **${kw.keyword}** (score: ${kw.score.toFixed(3)}, frequency: ${kw.frequency})\n`;
});
}
return markdown;
}
formatGraphAsMarkdown(data) {
const { nodes, edges, communities, metrics } = data;
let markdown = `### Graph Analysis\n\n`;
markdown += `- **Nodes:** ${metrics.nodeCount}\n`;
markdown += `- **Edges:** ${metrics.edgeCount}\n`;
markdown += `- **Density:** ${metrics.density.toFixed(3)}\n`;
markdown += `- **Average degree:** ${metrics.avgDegree.toFixed(1)}\n`;
markdown += `- **Communities:** ${communities.length}\n\n`;
if (communities.length > 0) {
markdown += `#### Communities\n\n`;
communities.forEach((community, index) => {
markdown += `${index + 1}. **${community.id}** (${community.size} members)\n`;
});
}
return markdown;
}
formatTemporalAsMarkdown(data) {
const { events, timeline, stats } = data;
let markdown = `### Temporal Analysis\n\n`;
markdown += `- **Total events:** ${stats.eventCount}\n`;
markdown += `- **Timeline span:** ${stats.timelineSpan} periods\n`;
markdown += `- **Duration:** ${Math.round(stats.duration / (24 * 60 * 60 * 1000))} days\n`;
markdown += `- **Event frequency:** ${stats.frequency.toFixed(2)} events/day\n\n`;
if (timeline.length > 0) {
markdown += `#### Timeline\n\n`;
timeline.slice(0, 10).forEach(period => {
markdown += `- **${period.period}**: ${period.count} events (avg score: ${period.avgScore.toFixed(2)})\n`;
});
}
return markdown;
}
formatContentForLLM(data, type, options) {
switch (type) {
case 'vector':
return this.formatEmbeddingsForLLM(data);
case 'text':
return this.formatKeywordsForLLM(data);
case 'structured':
return this.formatGraphForLLM(data);
case 'sequence':
return this.formatTemporalForLLM(data);
default:
return JSON.stringify(data, null, 2);
}
}
formatEmbeddingsForLLM(data) {
const { embeddings, aggregateStats } = data;
let content = `EMBEDDING ANALYSIS RESULTS:\n\n`;
content += `Model: ${aggregateStats.model}\n`;
content += `Total items: ${embeddings.length}\n`;
content += `Average similarity: ${aggregateStats.avgSimilarity.toFixed(3)}\n\n`;
if (embeddings.length > 0) {
content += `TOP SIMILAR ITEMS:\n`;
embeddings
.sort((a, b) => b.similarity - a.similarity)
.slice(0, 10)
.forEach((item, index) => {
content += `${index + 1}. [${item.similarity.toFixed(3)}] ${item.uri}\n`;
});
}
return content;
}
formatKeywordsForLLM(data) {
const { globalKeywords, summary, corpuscleKeywords } = data;
let content = `KEYWORD ANALYSIS RESULTS:\n\n`;
content += `Summary: ${summary}\n\n`;
content += `KEY TERMS:\n`;
globalKeywords.slice(0, 15).forEach((kw, index) => {
content += `${index + 1}. ${kw.keyword} (${kw.score.toFixed(3)})\n`;
});
if (corpuscleKeywords.length > 0) {
content += `\nCONTENT EXCERPTS:\n`;
corpuscleKeywords.slice(0, 5).forEach((item, index) => {
const topKeywords = item.keywords.slice(0, 3).map(k => k.keyword).join(', ');
content += `${index + 1}. Keywords: ${topKeywords}\n Content: ${item.content}\n\n`;
});
}
return content;
}
formatGraphForLLM(data) {
const { nodes, edges, communities, metrics } = data;
let content = `GRAPH ANALYSIS RESULTS:\n\n`;
content += `Network structure: ${nodes.length} nodes, ${edges.length} edges\n`;
content += `Density: ${metrics.density.toFixed(3)}\n`;
content += `Communities: ${communities.length}\n\n`;
// Top nodes by score
const topNodes = nodes
.sort((a, b) => (b.score || 0) - (a.score || 0))
.slice(0, 10);
content += `TOP ENTITIES:\n`;
topNodes.forEach((node, index) => {
content += `${index + 1}. ${node.label} (${node.type}, score: ${(node.score || 0).toFixed(3)})\n`;
});
if (communities.length > 0) {
content += `\nCOMMUNITIES:\n`;
communities.slice(0, 5).forEach((community, index) => {
content += `${index + 1}. ${community.id}: ${community.size} members\n`;
});
}
return content;
}
formatTemporalForLLM(data) {
const { events, timeline, sequences, stats } = data;
let content = `TEMPORAL ANALYSIS RESULTS:\n\n`;
content += `Time range: ${stats.duration / (24 * 60 * 60 * 1000)} days\n`;
content += `Total events: ${events.length}\n`;
content += `Event frequency: ${stats.frequency.toFixed(2)} events/day\n\n`;
content += `TIMELINE:\n`;
timeline.slice(0, 10).forEach(period => {
content += `${period.period}: ${period.count} events\n`;
});
if (sequences.length > 0) {
content += `\nEVENT SEQUENCES:\n`;
sequences.slice(0, 3).forEach((seq, index) => {
content += `${index + 1}. ${seq.events.length} events over ${Math.round(seq.duration / (24 * 60 * 60 * 1000))} days\n`;
});
}
return content;
}
/**
* Content naturally formatted for conversation
*/
formatContentNaturally(data, type) {
switch (type) {
case 'vector':
return this.formatEmbeddingsNaturally(data);
case 'text':
return this.formatKeywordsNaturally(data);
case 'structured':
return this.formatGraphNaturally(data);
case 'sequence':
return this.formatTemporalNaturally(data);
default:
return 'I found some data, but it\'s in a format I can\'t easily describe.';
}
}
formatEmbeddingsNaturally(data) {
const { embeddings, aggregateStats } = data;
let natural = `I analyzed ${embeddings.length} items using semantic embeddings. `;
if (aggregateStats.avgSimilarity > 0.7) {
natural += `The content shows high semantic similarity (average ${aggregateStats.avgSimilarity.toFixed(2)}), `;
natural += `suggesting these items are closely related in meaning.`;
} else if (aggregateStats.avgSimilarity > 0.3) {
natural += `The content shows moderate semantic relationships, with some related themes emerging.`;
} else {
natural += `The content is quite diverse, covering different topics and concepts.`;
}
return natural;
}
formatKeywordsNaturally(data) {
const { globalKeywords, summary } = data;
let natural = summary;
if (globalKeywords.length > 5) {
const topTerms = globalKeywords.slice(0, 5).map(k => k.keyword).join(', ');
natural += ` The most prominent terms are: ${topTerms}.`;
}
return natural;
}
formatGraphNaturally(data) {
const { nodes, communities, metrics } = data;
let natural = `I found a network of ${nodes.length} connected entities. `;
if (communities.length > 1) {
natural += `The network naturally groups into ${communities.length} communities, `;
natural += `suggesting distinct but related topic clusters.`;
} else {
natural += `The entities form a cohesive network with strong interconnections.`;
}
if (metrics.density > 0.1) {
natural += ` The network is well-connected with many relationships between entities.`;
}
return natural;
}
formatTemporalNaturally(data) {
const { events, stats } = data;
let natural = `I analyzed ${events.length} events spanning ${Math.round(stats.duration / (24 * 60 * 60 * 1000))} days. `;
if (stats.frequency > 1) {
natural += `The activity level is quite high, with about ${stats.frequency.toFixed(1)} events per day.`;
} else if (stats.frequency > 0.1) {
natural += `The activity is moderate, with events occurring regularly over time.`;
} else {
natural += `The events are spread out over a longer time period.`;
}
return natural;
}
/**
* Analysis and insight extraction
*/
analyzeContentType(data) {
if (data.embeddings) return 'semantic_embeddings';
if (data.globalKeywords) return 'keyword_extraction';
if (data.nodes && data.edges) return 'graph_structure';
if (data.events && data.timeline) return 'temporal_sequence';
return 'unknown';
}
assessComplexity(data) {
let complexity = 0;
if (data.embeddings) complexity += data.embeddings.length / 100;
if (data.globalKeywords) complexity += data.globalKeywords.length / 50;
if (data.nodes) complexity += data.nodes.length / 200;
if (data.events) complexity += data.events.length / 500;
return Math.min(1.0, complexity);
}
analyzeStructure(data) {
const structure = {
hierarchical: false,
networked: false,
sequential: false,
categorical: false
};
if (data.nodes && data.edges) structure.networked = true;
if (data.events && data.timeline) structure.sequential = true;
if (data.communities) structure.hierarchical = true;
if (data.globalKeywords) structure.categorical = true;
return structure;
}
extractInsights(data, representation) {
const insights = [];
switch (representation) {
case 'embedding':
if (data.aggregateStats?.avgSimilarity > 0.8) {
insights.push('High semantic coherence detected');
}
break;
case 'keywords':
if (data.stats?.coverageScore > 0.7) {
insights.push('Strong keyword coverage across content');
}
break;
case 'graph':
if (data.metrics?.density > 0.1) {
insights.push('Well-connected entity network');
}
break;
case 'temporal':
if (data.patterns?.length > 0) {
insights.push('Temporal patterns detected');
}
break;
}
return insights;
}
/**
* Helper methods for specific formatting tasks
*/
summarizeFilters(pan) {
if (!pan || Object.keys(pan).length === 0) return 'none';
const filters = [];
if (pan.topic) filters.push(`topic: ${pan.topic.value}`);
if (pan.entity) filters.push(`entities: ${pan.entity.count}`);
if (pan.temporal) filters.push('temporal constraints');
if (pan.geographic) filters.push('geographic bounds');
return filters.join(', ');
}
generateExecutiveSummary(data, navigation, analysis) {
let summary = `Analysis of corpus content using ${navigation.zoom} zoom level with ${navigation.tilt} representation. `;
if (analysis.insights.length > 0) {
summary += `Key insights: ${analysis.insights.join(', ')}. `;
}
summary += `Content complexity: ${(analysis.complexity * 100).toFixed(0)}%.`;
return summary;
}
extractKeyFindings(data, type, analysis) {
const findings = [];
switch (type) {
case 'vector':
if (data.aggregateStats) {
findings.push(`Semantic similarity: ${data.aggregateStats.avgSimilarity.toFixed(3)}`);
findings.push(`Content items analyzed: ${data.embeddings.length}`);
}
break;
case 'text':
if (data.stats) {
findings.push(`Unique keywords identified: ${data.stats.totalKeywords}`);
findings.push(`Keyword coverage: ${(data.stats.coverageScore * 100).toFixed(1)}%`);
}
break;
case 'structured':
if (data.metrics) {
findings.push(`Network density: ${data.metrics.density.toFixed(3)}`);
findings.push(`Communities detected: ${data.communities?.length || 0}`);
}
break;
case 'sequence':
if (data.stats) {
findings.push(`Event frequency: ${data.stats.frequency.toFixed(2)} events/day`);
findings.push(`Temporal sequences: ${data.sequences?.length || 0}`);
}
break;
}
return findings.map((finding, index) => `${index + 1}. ${finding}`).join('\n');
}
formatDetailedAnalysis(data, type) {
// Detailed analysis would go here - simplified for brevity
return `Detailed analysis of ${type} data with ${JSON.stringify(data).length} characters of raw data.`;
}
identifyPatterns(data, analysis) {
const patterns = [];
if (analysis.structure.networked) {
patterns.push('Network connectivity patterns identified');
}
if (analysis.structure.sequential) {
patterns.push('Temporal progression patterns observed');
}
if (analysis.complexity > 0.7) {
patterns.push('High complexity suggests rich interconnections');
}
return patterns.length > 0 ? patterns.map((p, i) => `${i + 1}. ${p}`).join('\n') : 'No significant patterns detected.';
}
/**
* Instruction and context enhancement
*/
addInstructions(content, options) {
if (!options.includeInstructions) return content;
const instructionSet = options.instructionSet || 'analysis';
const instructions = this.instructions[instructionSet];
if (!instructions) return content;
let instructionalContent = `${instructions.prefix}\n\n`;
instructionalContent += `${instructions.context}\n\n`;
instructionalContent += `${instructions.guidance}\n\n`;
instructionalContent += `---\n\n${content}\n\n---\n\n`;
instructionalContent += `${instructions.suffix}`;
return instructionalContent;
}
addContextMarkers(content, context, options) {
if (!options.contextMarkers) return content;
const markers = {
start: `<!-- ZPT_START: ${context.navigation.zoom}/${context.navigation.tilt} -->`,
end: `<!-- ZPT_END: ${new Date().toISOString()} -->`,
metadata: `<!-- ZPT_META: ${JSON.stringify(context.navigation)} -->`
};
return `${markers.start}\n${markers.metadata}\n\n${content}\n\n${markers.end}`;
}
/**
* Metadata formatting
*/
formatMetadataAsMarkdown(metadata, formatting) {
let md = '```yaml\n';
md += `timestamp: ${formatting.timestamp}\n`;
md += `projection_type: ${metadata.projection?.type || 'unknown'}\n`;
md += `processing_time: ${metadata.processingTime || 0}ms\n`;
md += '```';
return md;
}
formatMetadataForLLM(metadata, analysis) {
let meta = `Processing Details:\n`;
meta += `- Timestamp: ${new Date().toISOString()}\n`;
meta += `- Processing time: ${metadata.processingTime || 0}ms\n`;
if (analysis) {
meta += `- Content complexity: ${(analysis.complexity * 100).toFixed(0)}%\n`;
}
return meta;
}
formatAnalyticalMetadata(metadata, formatting) {
return this.formatMetadataAsMarkdown(metadata, formatting);
}
/**
* Utility methods
*/
estimateTokenCount(content) {
// Simple token estimation - 4 characters per token average
return Math.ceil(content.length / 4);
}
/**
* Get available formats
*/
getAvailableFormats() {
return Object.keys(this.formats);
}
/**
* Get format information
*/
getFormatInfo(formatName) {
return this.formats[formatName] ? { ...this.formats[formatName] } : null;
}
/**
* Get available instruction sets
*/
getAvailableInstructions() {
return Object.keys(this.instructions);
}
/**
* Get instruction set information
*/
getInstructionInfo(instructionSet) {
return this.instructions[instructionSet] ? { ...this.instructions[instructionSet] } : null;
}
/**
* Validate formatting options
*/
validateOptions(options) {
const issues = [];
if (options.format && !this.formats[options.format]) {
issues.push(`Unknown format: ${options.format}`);
}
if (options.instructionSet && !this.instructions[options.instructionSet]) {
issues.push(`Unknown instruction set: ${options.instructionSet}`);
}
return {
valid: issues.length === 0,
issues
};
}
}