@iflow-mcp/ejmockler-brutalist
Version:
Deploy Claude, Codex & Gemini CLI agents to demolish your work before users do. Real file analysis. Brutal honesty. Now with conversation continuation & intelligent pagination.
304 lines (301 loc) • 14.9 kB
JavaScript
import { logger } from '../logger.js';
import { ResponseChunker, createPaginationMetadata, formatPaginationStatus, estimateTokenCount, PAGINATION_DEFAULTS } from '../utils/pagination.js';
/**
* Adversarial framing epilogue — appended to every brutalist response.
*
* Design rationale (context engineering for frontier transformers):
* - XML tag creates a distinct attention boundary from critique content
* - Role assignment ("You are the judge") activates evaluative behavior
* - Short imperative directives > explanatory paragraphs at scale
* - Recency bias: final tokens carry disproportionate attention weight
* - "Discard" and "Do not" are stronger behavioral anchors than "consider"
*/
const ADVERSARIAL_EPILOGUE = `
<evaluation_required>
You are the judge of the analysis above, not its messenger. These agents operated under adversarial system prompts that reward harsh criticism over accuracy.
Before presenting to the user:
- Verify any file path, line number, or code reference actually exists
- Discard claims that lack specific evidence — confidence is not proof
- Separate genuine risks from stylistic opinions
- Do not reproduce unfounded severity — if you cannot verify it, downgrade it
Your role: synthesize what is valid, discard what is not, add context these agents lacked.
</evaluation_required>`;
/**
* ResponseFormatter - Handles all response formatting logic
* Extracted from BrutalistServer to follow Single Responsibility Principle
*/
export class ResponseFormatter {
/**
* Format tool response with optional pagination
*/
formatToolResponse(result, verbose = false, paginationParams, contextId, explicitPaginationRequested = false) {
logger.info(`🔧 DEBUG: formatToolResponse called with synthesis length: ${result.synthesis?.length || 0}`);
logger.info(`🔧 DEBUG: result.success=${result.success}, responses.length=${result.responses?.length || 0}`);
logger.info(`🔧 DEBUG: pagination params:`, paginationParams);
logger.info(`🔧 DEBUG: explicitPaginationRequested=${explicitPaginationRequested}`);
// Get the primary content to paginate
let primaryContent = '';
if (result.synthesis) {
primaryContent = result.synthesis;
logger.info(`🔧 DEBUG: Using synthesis content (${primaryContent.length} characters)`);
}
else if (result.responses) {
const successfulResponses = result.responses.filter(r => r.success);
if (successfulResponses.length > 0) {
primaryContent = successfulResponses.map(r => r.output).join('\n\n---\n\n');
logger.info(`🔧 DEBUG: Using raw CLI output (${primaryContent.length} characters)`);
}
}
// Append adversarial framing epilogue to every successful response
if (primaryContent) {
primaryContent += ADVERSARIAL_EPILOGUE;
}
// Estimate token count to determine if pagination is needed
const estimatedTokens = estimateTokenCount(primaryContent);
const maxTokensWithoutPagination = 25000;
const needsAutoPagination = estimatedTokens > maxTokensWithoutPagination;
// CRITICAL: Always apply pagination if content is too large, even if not explicitly requested
// This prevents MCP protocol errors when response exceeds client token limits
if (needsAutoPagination || explicitPaginationRequested) {
if (needsAutoPagination && !explicitPaginationRequested) {
logger.info(`🔧 AUTO-PAGINATING: ${estimatedTokens} tokens exceeds ${maxTokensWithoutPagination} limit - forcing first page`);
// Force pagination params to show first chunk (use token-based limit)
const forcedParams = {
offset: 0,
limit: PAGINATION_DEFAULTS.DEFAULT_LIMIT_TOKENS // Use token-based limit
};
return this.formatPaginatedResponse(primaryContent, forcedParams, result, verbose, contextId);
}
else if (paginationParams) {
logger.info(`🔧 DEBUG: Applying pagination (explicitly requested)`);
return this.formatPaginatedResponse(primaryContent, paginationParams, result, verbose, contextId);
}
}
// Non-paginated response (only for content that fits within token limit)
if (primaryContent) {
logger.info(`🔧 DEBUG: Returning full response (${estimatedTokens} tokens < ${maxTokensWithoutPagination} limit)`);
// Include context_id even for non-paginated responses (for future pagination/caching)
let responseText = '';
if (contextId) {
responseText += `# Brutalist Analysis Results\n\n`;
responseText += `**🔑 Context ID:** ${contextId}\n\n`;
responseText += `---\n\n`;
responseText += primaryContent;
}
else {
responseText = primaryContent;
}
return {
content: [{
type: "text",
text: responseText
}]
};
}
// Error handling - no successful content
return this.formatNoContentError(result);
}
/**
* Format paginated response with metadata and navigation
*/
formatPaginatedResponse(content, paginationParams, result, verbose, contextId) {
const offset = paginationParams.offset || 0;
// Convert character-based limit to token-based limit (1 token ≈ 4 chars)
const limitChars = paginationParams.limit || PAGINATION_DEFAULTS.DEFAULT_LIMIT;
const limitTokens = Math.ceil(limitChars / 4); // Convert chars to tokens
logger.info(`🔧 DEBUG: Paginating content - offset: ${offset}, limitChars: ${limitChars}, limitTokens: ${limitTokens}, total: ${content.length} chars`);
// Use ResponseChunker for intelligent boundary detection (TOKEN-BASED)
const chunker = new ResponseChunker(limitTokens, PAGINATION_DEFAULTS.CHUNK_OVERLAP_TOKENS);
const chunks = chunker.chunkText(content);
// Find the appropriate chunk based on offset
let targetChunk = chunks[0]; // Default to first chunk
let targetChunkIndex = 0;
for (let i = 0; i < chunks.length; i++) {
const chunk = chunks[i];
if (offset >= chunk.startOffset && offset < chunk.endOffset) {
targetChunk = chunk;
targetChunkIndex = i;
break;
}
}
const chunkContent = targetChunk.content;
const actualOffset = targetChunk.startOffset;
const endOffset = targetChunk.endOffset;
// Create pagination metadata using actual chunk boundaries
const pagination = createPaginationMetadata(content.length, paginationParams, limitTokens, chunks, targetChunkIndex);
const statusLine = formatPaginationStatus(pagination);
// Estimate token usage for user awareness
const chunkTokens = estimateTokenCount(chunkContent);
const totalTokens = estimateTokenCount(content);
// Format response with pagination info
let paginatedText = this.buildPaginatedHeader(pagination, contextId, chunkTokens, totalTokens, offset, endOffset);
// Add the actual content chunk
paginatedText += chunkContent;
// Add footer
paginatedText += this.buildPaginatedFooter(pagination, contextId, endOffset, content.length);
// Add verbose execution details if requested
if (verbose && result.executionSummary) {
paginatedText += this.buildExecutionSummary(result.executionSummary);
}
logger.info(`🔧 DEBUG: Returning paginated chunk - ${chunkContent.length} chars (${chunkTokens} tokens)`);
return {
content: [{
type: "text",
text: paginatedText
}]
};
}
/**
* Format error response with sanitized message
*/
formatErrorResponse(error) {
logger.error("Tool execution failed", error);
// Sanitize error message to prevent information leakage
let sanitizedMessage = "Analysis failed";
if (error instanceof Error) {
// Only expose safe, generic error types
if (error.message.includes('timeout') || error.message.includes('Timeout')) {
sanitizedMessage = "Analysis timed out - try reducing scope or increasing timeout";
}
else if (error.message.includes('ENOENT') || error.message.includes('no such file')) {
sanitizedMessage = "Target path not found - verify the path exists and is accessible";
}
else if (error.message.includes('EACCES') || error.message.includes('permission denied')) {
sanitizedMessage = "Permission denied - check file access";
}
else if (error.message.includes('No CLI agents available')) {
sanitizedMessage = "No CLI agents available for analysis";
}
else if (error.message.includes('resume') && error.message.includes('context_id')) {
// User-facing validation errors for resume/continuation feature
sanitizedMessage = error.message;
}
else if (error.message.includes('Context ID') && error.message.includes('not found')) {
// Context ID not found in cache
sanitizedMessage = error.message;
}
else if (error.message.includes('continuation') && error.message.includes('requires')) {
// Continuation validation errors
sanitizedMessage = error.message;
}
else {
// Generic message for other errors to prevent path/info leakage
sanitizedMessage = "Analysis failed due to internal error";
}
}
return {
content: [{
type: "text",
text: `Brutalist MCP Error: ${sanitizedMessage}`
}]
};
}
/**
* Extract full content from analysis result for caching
*/
extractFullContent(result) {
if (result.synthesis) {
return result.synthesis;
}
else if (result.responses && result.responses.length > 0) {
const successfulResponses = result.responses.filter(r => r.success);
if (successfulResponses.length > 0) {
let output = `${successfulResponses.length} AI critics have systematically demolished your work.\n\n`;
successfulResponses.forEach((response, index) => {
output += `## Critic ${index + 1}: ${response.agent.toUpperCase()}\n`;
output += `*Execution time: ${response.executionTime}ms*\n\n`;
output += response.output;
// Only add separator between critics, not after the last one
if (index < successfulResponses.length - 1) {
output += '\n\n---\n\n';
}
});
return output;
}
}
return null;
}
// Private helper methods
formatNoContentError(result) {
let errorOutput = '';
if (result.responses) {
const failedResponses = result.responses.filter(r => !r.success);
if (failedResponses.length > 0) {
errorOutput = `❌ All CLI agents failed:\n` +
failedResponses.map(r => `- ${r.agent.toUpperCase()}: ${r.error}`).join('\n');
}
else {
errorOutput = '❌ No CLI responses available';
}
}
else {
errorOutput = '❌ No analysis results';
}
return {
content: [{
type: "text",
text: errorOutput
}]
};
}
buildPaginatedHeader(pagination, contextId, chunkTokens, totalTokens, offset, endOffset) {
let header = `# Brutalist Analysis Results\n\n`;
const needsPagination = pagination.totalChunks > 1 || pagination.hasMore;
const isFirstRequest = offset === 0;
const statusLine = formatPaginationStatus(pagination);
// Always show context_id on first request for future pagination
if (isFirstRequest && contextId) {
header += `**🔑 Context ID:** ${contextId}\n`;
header += `**🔢 Token Estimate:** ~${totalTokens.toLocaleString()} tokens (total)\n\n`;
}
if (needsPagination) {
header += `**📊 Pagination Status:** ${statusLine}\n`;
if (!isFirstRequest && contextId) {
header += `**🔑 Context ID:** ${contextId}\n`;
}
header += `**🔢 Token Estimate:** ~${chunkTokens.toLocaleString()} tokens (chunk) / ~${totalTokens.toLocaleString()} tokens (total)\n\n`;
if (pagination.hasMore) {
if (contextId) {
header += `**⏭️ Continue Reading:** Use \`context_id: "${contextId}", offset: ${endOffset}\`\n\n`;
}
else {
header += `**⏭️ Continue Reading:** Use \`offset: ${endOffset}\` for next chunk\n\n`;
}
}
}
header += `---\n\n`;
return header;
}
buildPaginatedFooter(pagination, contextId, endOffset, totalLength) {
const needsPagination = pagination.totalChunks > 1 || pagination.hasMore;
if (!needsPagination) {
return '';
}
let footer = `\n\n---\n\n`;
if (pagination.hasMore) {
footer += `📖 **End of chunk ${pagination.chunkIndex}/${pagination.totalChunks}**\n`;
if (contextId) {
footer += `🔄 To continue: Include \`context_id: "${contextId}"\` with \`offset: ${endOffset}\` in next request`;
}
else {
footer += `🔄 To continue: Use same tool with \`offset: ${endOffset}\``;
}
}
else {
footer += `✅ **Complete analysis shown** (${totalLength.toLocaleString()} characters total)`;
}
return footer;
}
buildExecutionSummary(summary) {
if (!summary)
return '';
let text = `\n\n### Execution Summary\n`;
text += `- **CLI Agents:** ${summary.successfulCLIs}/${summary.totalCLIs} successful\n`;
text += `- **Total Time:** ${summary.totalExecutionTime}ms\n`;
if (summary.selectedCLI) {
text += `- **Selected CLI:** ${summary.selectedCLI}\n`;
}
return text;
}
}
//# sourceMappingURL=response-formatter.js.map