Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 27 additions & 25 deletions website/docs/overview/architecture/system-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ The Semantic Router implements a sophisticated Mixture-of-Models (MoM) architect

## High-Level Architecture Overview

```mermaid
graph TB
import ZoomableMermaid from '@site/src/components/ZoomableMermaid';

<ZoomableMermaid title="System Architecture Overview" defaultZoom={5.5}>
{`graph TB
subgraph "Client Layer"
Client1[Web Application]
Client2[Mobile App]
Expand Down Expand Up @@ -62,8 +64,8 @@ graph TB

ExtProc --> Prometheus
Prometheus --> Grafana
ExtProc --> Logs
```
ExtProc --> Logs`}
</ZoomableMermaid>

## Core Components

Expand Down Expand Up @@ -113,7 +115,7 @@ http_filters:
type OpenAIRouter struct {
Config *config.RouterConfig
CategoryDescriptions []string
Classifier *classification.Classifier // ModernBERT-based
Classifier *classification.Classifier // ModernBERT-based
PIIChecker *pii.PolicyChecker // Privacy protection
Cache *cache.SemanticCache // Performance optimization
ToolsDatabase *tools.ToolsDatabase // Tool selection
Expand All @@ -125,8 +127,8 @@ type OpenAIRouter struct {

**Processing Pipeline**:

```mermaid
sequenceDiagram
<ZoomableMermaid title="Processing Pipeline">
{`sequenceDiagram
participant E as Envoy
participant R as Router
participant C as Classifier
Expand All @@ -152,17 +154,17 @@ sequenceDiagram
E->>R: Response from model
R->>Ca: Cache semantic representation
R->>E: Final response
end
```
end`}
</ZoomableMermaid>

### 3. Classification System - Decision Engine

The classification system uses ModernBERT models for multiple classification tasks:

#### Category Classification

```mermaid
graph LR
<ZoomableMermaid title="Category Classification System">
{`graph LR
Query[User Query] --> Tokenizer[ModernBERT Tokenizer]
Tokenizer --> Encoder[ModernBERT Encoder<br/>768-dim embeddings]
Encoder --> ClassifierHead[Classification Head<br/>Category Prediction]
Expand All @@ -182,8 +184,8 @@ graph LR
Decision --> Code
Decision --> General
Decision --> Science
Decision --> Business
```
Decision --> Business`}
</ZoomableMermaid>

#### Multi-Task Architecture

Expand Down Expand Up @@ -214,8 +216,8 @@ class SemanticRouter:

### Request Processing Flow

```mermaid
graph TB
<ZoomableMermaid title="Request Processing Flow" defaultZoom={1.3}>
{`graph TB
Start([Client Request]) --> EnvoyReceive[Envoy Receives Request]

EnvoyReceive --> ExtProcSend[Send to ExtProc<br/>Headers + Body]
Expand Down Expand Up @@ -257,13 +259,13 @@ graph TB
style JailbreakCheck fill:#f44336
style CategoryClassification fill:#4caf50
style CacheCheck fill:#2196f3
style RoutingDecision fill:#9c27b0
```
style RoutingDecision fill:#9c27b0`}
</ZoomableMermaid>

### Response Processing Flow

```mermaid
sequenceDiagram
<ZoomableMermaid title="Response Processing Flow">
{`sequenceDiagram
participant C as Client
participant E as Envoy
participant R as Router
Expand All @@ -285,8 +287,8 @@ sequenceDiagram
R->>Me: Record routing metrics

R->>E: Processed Response
E->>C: Final Response to Client
```
E->>C: Final Response to Client`}
</ZoomableMermaid>

## Threading and Concurrency Model

Expand Down Expand Up @@ -514,8 +516,8 @@ func (cb *CircuitBreaker) Call(operation func() error) error {

### Fallback Strategies

```mermaid
graph TB
<ZoomableMermaid title="Fallback Strategies" defaultZoom={1.5}>
{`graph TB
Request[Incoming Request] --> PrimaryRoute[Primary Routing Decision]

PrimaryRoute --> ModelA{Model A<br/>Available?}
Expand All @@ -534,8 +536,8 @@ graph TB
ProcessA --> Success[Successful Response]
ProcessB --> Success
ProcessGeneral --> Success
ReturnCached --> Success
```
ReturnCached --> Success`}
</ZoomableMermaid>

## Monitoring and Observability

Expand Down
230 changes: 230 additions & 0 deletions website/src/components/ZoomableMermaid/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
import React, { useState, useRef, useEffect, useCallback } from 'react'
import { createPortal } from 'react-dom'
import Mermaid from '@theme/Mermaid'
import styles from './styles.module.css'

const ZoomableMermaid = ({ children, title, defaultZoom = 1.2 }) => {
const [isModalOpen, setIsModalOpen] = useState(false)
const [isHovered, setIsHovered] = useState(false)
const [zoomLevel, setZoomLevel] = useState(defaultZoom) // Use defaultZoom prop
const modalRef = useRef(null)
const containerRef = useRef(null)

const openModal = useCallback(() => {
setIsModalOpen(true)
setZoomLevel(defaultZoom) // Reset to default zoom when opening
document.body.style.overflow = 'hidden'
}, [defaultZoom])

const closeModal = useCallback(() => {
setIsModalOpen(false)
document.body.style.overflow = 'unset'
// Return focus to the original container
if (containerRef.current) {
containerRef.current.focus()
}
}, [])

const zoomIn = useCallback(() => {
setZoomLevel(prev => Math.min(prev + 0.2, 3.0)) // Max 300%
}, [])

const zoomOut = useCallback(() => {
setZoomLevel(prev => Math.max(prev - 0.2, 0.5)) // Min 50%
}, [])

const resetZoom = useCallback(() => {
setZoomLevel(defaultZoom) // Reset to custom default instead of hardcoded 1.2
}, [defaultZoom])

useEffect(() => {
const handleEscape = (e) => {
if (e.key === 'Escape' && isModalOpen) {
closeModal()
}
}

const handleClickOutside = (e) => {
if (modalRef.current && !modalRef.current.contains(e.target)) {
closeModal()
}
}

const handleKeydown = (e) => {
if (!isModalOpen) return

if (e.key === '=' || e.key === '+') {
e.preventDefault()
zoomIn()
}
else if (e.key === '-') {
e.preventDefault()
zoomOut()
}
else if (e.key === '0') {
e.preventDefault()
resetZoom()
}
}

if (isModalOpen) {
document.addEventListener('keydown', handleEscape)
document.addEventListener('mousedown', handleClickOutside)
document.addEventListener('keydown', handleKeydown)

// Focus the modal content when opened
setTimeout(() => {
if (modalRef.current) {
modalRef.current.focus()
}
}, 100)
}

return () => {
document.removeEventListener('keydown', handleEscape)
document.removeEventListener('mousedown', handleClickOutside)
document.removeEventListener('keydown', handleKeydown)
}
}, [isModalOpen, closeModal, zoomIn, zoomOut, resetZoom])

// Cleanup on unmount
useEffect(() => {
return () => {
document.body.style.overflow = 'unset'
}
}, [])

const handleKeyDown = (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault()
openModal()
}
}

const modalContent = (
<div
className={styles.modal}
role="dialog"
aria-modal="true"
aria-labelledby={title ? 'modal-title' : undefined}
aria-describedby="modal-description"
>
<div
className={styles.modalContent}
ref={modalRef}
tabIndex={-1}
>
<div className={styles.modalHeader}>
{title && (
<h3 id="modal-title" className={styles.modalTitle}>
{title}
</h3>
)}
<div className={styles.modalControls}>
<span className={styles.zoomIndicator}>
{Math.round(zoomLevel * 100)}
%
</span>
<button
className={styles.zoomButton}
onClick={zoomOut}
disabled={zoomLevel <= 0.5}
aria-label="Reduce the size of the chart"
type="button"
title="Reduce (Shortcut key: -)"
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<circle cx="11" cy="11" r="8" />
<path d="M8 11h6" />
<path d="m21 21-4.35-4.35" />
</svg>
</button>
<button
className={styles.resetButton}
onClick={resetZoom}
aria-label={`Reset to default zoom level ${Math.round(defaultZoom * 100)}%`}
type="button"
title={`Reset to default zoom level ${Math.round(defaultZoom * 100)}% (Shortcut key: 0)`}
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<path d="M3 3l18 18" />
<path d="m19 4-7 7-7-7" />
<path d="m5 20 7-7 7 7" />
</svg>
</button>
<button
className={styles.zoomButton}
onClick={zoomIn}
disabled={zoomLevel >= 3.0}
aria-label="Enlarge the chart"
type="button"
title="Enlarge (Shortcut key: +)"
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<circle cx="11" cy="11" r="8" />
<path d="M8 11h6" />
<path d="M11 8v6" />
<path d="m21 21-4.35-4.35" />
</svg>
</button>
<button
className={styles.closeButton}
onClick={closeModal}
aria-label="Close the zoomed view"
type="button"
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<line x1="18" y1="6" x2="6" y2="18" />
<line x1="6" y1="6" x2="18" y2="18" />
</svg>
</button>
</div>
</div>
<div
className={styles.modalBody}
id="modal-description"
aria-label="Enlarged Mermaid diagram"
>
<div
className={styles.diagramContainer}
style={{ transform: `scale(${zoomLevel})`, transformOrigin: 'center' }}
>
<Mermaid value={children} />
</div>
</div>
</div>
</div>
)

return (
<>
<div
ref={containerRef}
className={`${styles.mermaidContainer} ${isHovered ? styles.hovered : ''}`}
onClick={openModal}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
role="button"
tabIndex={0}
onKeyDown={handleKeyDown}
aria-label={`Click to enlarge ${title || 'Mermaid diagram'}`}
aria-expanded={isModalOpen}
>
<div className={styles.zoomHint} aria-hidden="true">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<circle cx="11" cy="11" r="8" />
<path d="m21 21-4.35-4.35" />
<path d="M11 8v6" />
<path d="M8 11h6" />
</svg>
<span>Click to enlarge</span>
</div>
<Mermaid value={children} />
</div>

{isModalOpen && createPortal(modalContent, document.body)}
</>
)
}

export default ZoomableMermaid
Loading
Loading