v0.5.2 release - Contributors, Sponsors and Enquiries are most welcome 😌

Content Formatting

Transform agent responses into multiple formats including text, markdown, HTML, and React-compatible output with built-in syntax highlighting, theming, and security features.

✨ New Feature

Content formatting is now available in @lov3kaizen/agentsea-core 0.1.0+. It provides automatic conversion of agent responses into various formats suitable for web apps, APIs, and user interfaces.

What is Content Formatting?

Content formatting automatically transforms agent responses into structured formats optimized for different use cases. Whether you're building a web application, REST API, or chat interface, AgentSea can format responses with rich content like code blocks, tables, and lists.

Supported Output Formats

📝 Text

Plain text output with no processing. Best for CLI tools and simple text interfaces.

📄 Markdown

Preserves markdown formatting with metadata extraction. Ideal for documentation and markdown editors.

🌐 HTML

Fully rendered HTML with syntax highlighting, theming, and sanitization. Perfect for web applications.

⚛️ React

React-compatible HTML with data attributes for component hydration. Optimized for React apps.

Quick Start

Enable formatting by setting the outputFormat in your agent configuration:

typescript
import { Agent, AnthropicProvider, ToolRegistry } from '@lov3kaizen/agentsea-core';

const provider = new AnthropicProvider({
  apiKey: process.env.ANTHROPIC_API_KEY,
});

const agent = new Agent(
  {
    name: 'my-agent',
    description: 'Agent with formatting support',
    model: 'claude-3-5-sonnet-20241022',
    provider: 'anthropic',
    outputFormat: 'html', // 'text' | 'markdown' | 'html' | 'react'
    formatOptions: {
      includeMetadata: true,
      sanitizeHtml: true,
      highlightCode: true,
      theme: 'dark',
    },
  },
  provider,
  new ToolRegistry(),
);

const response = await agent.execute('Explain async/await', {
  conversationId: 'conv-1',
  sessionData: {},
  history: [],
});

console.log(response.formatted?.rendered); // HTML output
console.log(response.formatted?.metadata); // Content structure info

Format Options

Customize formatting behavior with these options:

OptionTypeDescription
includeMetadatabooleanExtract metadata about content structure (code blocks, tables, lists, links)
sanitizeHtmlbooleanRemove potentially dangerous HTML (script tags, event handlers, javascript: protocol)
highlightCodebooleanAdd syntax highlighting classes to code blocks (works with highlight.js)
themestringApply theme wrapper: 'light', 'dark', or 'auto'

Response Structure

When formatting is enabled, the response includes a formatted field:

json
{
  content: "# Title\n\n**Bold text**...",
  formatted: {
    raw: "# Title\n\n**Bold text**...",
    format: "html",
    rendered: "<div class=\"agentsea-content\" data-theme=\"dark\">...</div>",
    metadata: {
      hasCodeBlocks: true,
      hasTables: false,
      hasLists: true,
      links: [{ text: "Link", url: "https://..." }]
    }
  },
  metadata: {
    tokensUsed: 1234,
    latencyMs: 2000,
    iterations: 1
  }
}

Using with React

The @lov3kaizen/agentsea-react package provides ready-to-use components:

typescript
import { AgentResponse } from '@lov3kaizen/agentsea-react';

function MyComponent({ response }) {
  return (
    <AgentResponse
      response={response}
      showMetadata={true}
      theme="dark"
      components={{
        // Custom component overrides
        code: ({ className, children }) => (
          <MyCustomCode className={className}>
            {children}
          </MyCustomCode>
        ),
      }}
    />
  );
}

Streaming Responses

Render responses as they stream with the StreamingResponse component:

typescript
import { StreamingResponse } from '@lov3kaizen/agentsea-react';

function MyStreamingComponent() {
  const [stream, setStream] = useState(null);

  const startStream = async () => {
    const streamGenerator = agent.executeStream(input, context);
    setStream(streamGenerator);
  };

  return (
    <StreamingResponse
      stream={stream}
      showMetadata={true}
      theme="dark"
      onComplete={(content) => console.log('Done:', content)}
    />
  );
}

Using with NestJS

Configure formatting in your agent decorator:

typescript
import { AgentDecorator } from '@lov3kaizen/agentsea-nestjs';

@AgentDecorator({
  name: 'documentation-agent',
  description: 'Agent that generates formatted documentation',
  model: 'claude-3-5-sonnet-20241022',
  provider: 'anthropic',
  outputFormat: 'html',
  formatOptions: {
    includeMetadata: true,
    sanitizeHtml: true,
    highlightCode: true,
    theme: 'dark',
  },
})
class DocumentationAgent {}

Runtime Format Override

Override the format in API requests:

typescript
// POST /api/agent/execute
{
  "input": "Explain async/await with code examples",
  "outputFormat": "html",
  "formatOptions": {
    "includeMetadata": true,
    "sanitizeHtml": true,
    "highlightCode": true,
    "theme": "dark"
  }
}

Manual Formatting

Use the ContentFormatter utility for manual formatting:

typescript
import { ContentFormatter } from '@lov3kaizen/agentsea-core';

// Format content
const formatted = ContentFormatter.format(
  '# Title\n\nSome **markdown** content',
  'html',
  {
    includeMetadata: true,
    sanitizeHtml: true,
    highlightCode: true,
    theme: 'dark',
  }
);

console.log(formatted.rendered); // HTML output
console.log(formatted.metadata); // Content structure info

// Detect format
const detectedFormat = ContentFormatter.detectFormat('<h1>Hello</h1>');
console.log(detectedFormat); // 'html'

Security Features

When sanitizeHtml is enabled, the formatter removes:

  • <script> tags and inline scripts
  • Event handlers like onclick, onload, etc.
  • javascript: protocol in links

⚠️ Security Best Practice

Always enable sanitizeHtml: true when displaying HTML content to users to prevent XSS attacks.

Content Metadata

When includeMetadata is enabled, you get information about the content structure:

typescript
const response = await agent.execute(input, context);

if (response.formatted?.metadata?.hasCodeBlocks) {
  // Load syntax highlighting library
  import('highlight.js/styles/github-dark.css');
}

if (response.formatted?.metadata?.hasTables) {
  // Enable table styling
  enableTableStyles();
}

// Access extracted links
response.formatted?.metadata?.links?.forEach(link => {
  console.log(`Found link: ${link.text} -> ${link.url}`);
});

Use Cases

📱 Chat Applications

Use markdown or HTML format for rich chat messages with code blocks and formatting.

outputFormat: 'markdown'

🌐 Web Applications

Use HTML format with theming and syntax highlighting for web display.

outputFormat: 'html'

⚛️ React Apps

Use React format with @lov3kaizen/agentsea-react components for seamless integration.

outputFormat: 'react'

📝 Documentation Generation

Use markdown format to generate documentation that can be committed to repositories.

outputFormat: 'markdown'

🔌 REST APIs

Let API consumers choose their preferred format via request parameters.

Runtime override supported

Best Practices

  • Enable sanitizeHtml for user-facing HTML to prevent XSS attacks
  • Use includeMetadata to conditionally load resources based on content (e.g., syntax highlighters)
  • Choose the right format for your use case: text for CLI, HTML for web, React for React apps
  • Use theme: 'auto' to respect user's system preferences
  • Allow runtime format override in APIs for maximum flexibility
  • Cache formatted content to avoid reprocessing the same content

Installation

Formatting is included in the core package. For React components, install the React package:

bash
# Core package (includes formatting)
pnpm add @lov3kaizen/agentsea-core

# React components (optional)
pnpm add @lov3kaizen/agentsea-react

# For syntax highlighting in HTML
pnpm add highlight.js

Next Steps