docs(diagrams): create 8 canonical Mermaid sources + folder structure

Introduce docs/diagrams/ with the README index and 8 versioned Mermaid
sources that reflect the v3.8.0 platform:

- request-pipeline.mmd     /v1/chat/completions request pipeline
- auto-combo-9factor.mmd   Auto-Combo 9-factor scoring weights
- resilience-3layers.mmd   Provider breaker / cooldown / model lockout
- i18n-flow.mmd            Hash-based incremental doc translation
- mcp-tools-37.mmd         MCP Server tool inventory by category
- cloud-agent-flow.mmd     Codex / Devin / Jules task lifecycle
- authz-pipeline.mmd       3-class authz pipeline (PUBLIC/CLIENT_API/MANAGEMENT)
- db-schema-overview.mmd   Selected core SQLite relations

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
diegosouzapw
2026-05-13 13:53:56 -03:00
parent 918a539baf
commit 675668c430
9 changed files with 224 additions and 0 deletions

48
docs/diagrams/README.md Normal file
View File

@@ -0,0 +1,48 @@
# Diagrams
Mermaid sources (`.mmd`) and exported SVGs for OmniRoute v3.8.0 architecture flows.
## Canonical diagrams
| Source | Exported | Used in |
| -------------------------------------------------- | ---------------------------------------- | ---------------------------------------------------- |
| [request-pipeline.mmd](./request-pipeline.mmd) | [SVG](./exported/request-pipeline.svg) | docs/ARCHITECTURE.md, docs/CODEBASE_DOCUMENTATION.md |
| [auto-combo-9factor.mmd](./auto-combo-9factor.mmd) | [SVG](./exported/auto-combo-9factor.svg) | docs/AUTO-COMBO.md |
| [resilience-3layers.mmd](./resilience-3layers.mmd) | [SVG](./exported/resilience-3layers.svg) | docs/RESILIENCE_GUIDE.md, CLAUDE.md |
| [i18n-flow.mmd](./i18n-flow.mmd) | [SVG](./exported/i18n-flow.svg) | docs/I18N.md |
| [mcp-tools-37.mmd](./mcp-tools-37.mmd) | [SVG](./exported/mcp-tools-37.svg) | docs/MCP-SERVER.md |
| [cloud-agent-flow.mmd](./cloud-agent-flow.mmd) | [SVG](./exported/cloud-agent-flow.svg) | docs/CLOUD_AGENT.md |
| [authz-pipeline.mmd](./authz-pipeline.mmd) | [SVG](./exported/authz-pipeline.svg) | docs/AUTHZ_GUIDE.md |
| [db-schema-overview.mmd](./db-schema-overview.mmd) | [SVG](./exported/db-schema-overview.svg) | docs/CODEBASE_DOCUMENTATION.md |
## How to update
1. Edit `*.mmd`.
2. Re-render: `npm run docs:render-diagrams` (uses `@mermaid-js/mermaid-cli`).
3. Commit both `.mmd` and `.svg`.
If `@mermaid-js/mermaid-cli` is not available locally, install it once:
```bash
npm install -g @mermaid-js/mermaid-cli
```
The script renders every `.mmd` in `docs/diagrams/` into `docs/diagrams/exported/*.svg`
with a white background, suitable for both dark and light themes.
## Linking from a doc
```markdown
![Request pipeline](./diagrams/exported/request-pipeline.svg)
> Source: [diagrams/request-pipeline.mmd](./diagrams/request-pipeline.mmd)
```
## Conventions
- One concept per diagram. Don't try to fit the whole platform in one chart.
- Keep node labels short (36 words). Use `<br/>` for line breaks inside nodes.
- Prefer `flowchart LR` for pipelines and `flowchart TB` for layered models.
- Use `sequenceDiagram` for interactive (request/response) flows.
- Use `erDiagram` for database schema overviews.
- Update both `.mmd` and `.svg` in the same commit. Keep them in lock-step.

View File

@@ -0,0 +1,23 @@
%% AuthZ pipeline (3 route classes + policy evaluation)
%% Reflects: src/middleware.ts, src/server/authz/pipeline.ts,
%% src/server/authz/policies/{public,clientApi,management}.ts
%% v3.8.0
flowchart LR
Req["Incoming request"] --> Strip["Strip trusted internal headers<br/>(x-omniroute-auth-*)"]
Strip --> Classify["classifyRoute()"]
Classify -->|PUBLIC| PubP["publicPolicy<br/>(login, health, status)"]
Classify -->|CLIENT_API| CliP["clientApiPolicy<br/>(/api/v1/*, /v1/*)"]
Classify -->|MANAGEMENT| MgmtP["managementPolicy<br/>(dashboard, settings, admin)"]
PubP -->|allow| Stamp["Stamp x-omniroute-auth-*<br/>(kind / id / label / scopes)"]
CliP -->|extract Bearer| Validate["validateApiKey()"]
Validate -->|valid| Stamp
Validate -->|"invalid (REQUIRE_API_KEY=true)"| Reject401["401 AUTH_002"]
Validate -->|"absent (REQUIRE_API_KEY=false)"| Anon["anonymous fallthrough"] --> Stamp
MgmtP -->|session ok| Stamp
MgmtP -->|Bearer w/ manage scope| Stamp
MgmtP -->|"Bearer invalid"| Reject403["403 AUTH_001"]
MgmtP -->|no auth| Reject401Mgmt["401 / 302 /login"]
Stamp --> Handler["Handler<br/>(uses assertAuth)"]

View File

@@ -0,0 +1,23 @@
%% Auto-Combo 9-factor scoring
%% Reflects: open-sse/services/autoCombo/scoring.ts (DEFAULT_WEIGHTS, sum = 1.0)
%% v3.8.0
flowchart TB
Request["Incoming request"] --> Candidates["Eligible candidates<br/>(provider × model × account)"]
Candidates --> Score["Compute composite score<br/>per candidate"]
subgraph Factors["9-factor scoring weights (sum = 1.0)"]
f1["health (0.22)"]
f2["quota (0.17)"]
f3["costInv (0.17)"]
f4["latencyInv (0.13)"]
f5["taskFit (0.08)"]
f6["specificityMatch (0.08)"]
f7["stability (0.05)"]
f8["tierPriority (0.05)"]
f9["tierAffinity (0.05)"]
end
Score --> Factors
Factors --> Final["Sort by score<br/>(desc)"]
Final --> Top["Pick top-N targets"]
Top --> Dispatch["Dispatch sequentially<br/>(short-circuit on success)"]

View File

@@ -0,0 +1,32 @@
%% Cloud Agent task lifecycle
%% Reflects: src/lib/cloudAgent/* and src/app/api/v1/agents/tasks/*
%% Supported agents: codex-cloud, devin, jules
%% v3.8.0
sequenceDiagram
participant U as User
participant API as /v1/agents/tasks
participant Reg as Cloud Agent Registry
participant Ag as Cloud Agent<br/>(codex-cloud / devin / jules)
participant DB as SQLite domain DB
U->>API: POST createTask (description, sources)
API->>API: Zod validation + AuthZ (management)
API->>Reg: getAgent(providerId)
Reg->>Ag: instantiate with credentials
Ag->>Ag: createTask() returns planning
Ag-->>API: taskId + status: planning
API->>DB: insertCloudAgentTask
API-->>U: taskId
U->>API: GET /tasks/:id (poll)
API->>Ag: getStatus(externalId)
Ag-->>API: status, plan, messages
API->>DB: updateCloudAgentTask
API-->>U: snapshot
U->>API: POST approvePlan
API->>Ag: approvePlan(externalId)
Ag-->>API: status: running
Note over Ag: Async execution upstream
Ag-->>DB: stream events / final result

View File

@@ -0,0 +1,16 @@
%% Database schema overview (selected core tables)
%% Reflects: src/lib/db/* (45+ modules, 55 migrations)
%% v3.8.0
erDiagram
api_keys ||--o{ api_key_usage : tracks
api_keys ||--o{ rate_limits : enforces
providers ||--o{ provider_connections : holds
provider_connections ||--o{ domain_circuit_breakers : protected_by
combos ||--o{ combo_targets : contains
combos ||--o{ combo_executions : logs
spend_buffer ||--o{ usage_aggregations : flushed_to
memory_documents ||--o{ memory_chunks : split_into
skills_runs ||--o{ skills_logs : produced
agent_tasks ||--o{ agent_task_events : streams
audit_log }|--|| api_keys : by
mcp_audit }|--|| api_keys : by

View File

@@ -0,0 +1,14 @@
%% Incremental hash-based i18n pipeline
%% Reflects: scripts/i18n/* and docs/i18n/<locale>/*.md mirror layout
%% v3.8.0
flowchart LR
Src["Source MDs<br/>(CLAUDE.md, docs/**/*.md)"] --> Hash["sha256 hash"]
Hash --> State[".i18n-state.json"]
State -->|diff| Dirty["Mark source dirty"]
Dirty --> Loop{"For each locale<br/>(39 langs)"}
Loop --> LLM["OmniRoute<br/>/chat/completions<br/>(cx/gpt-5.4-mini)"]
LLM --> Target["Write<br/>docs/i18n/&lt;locale&gt;/&lt;rel-path&gt;.md"]
Target --> State
Target --> CI{"CI drift check<br/>(npm run i18n:check)"}
CI -->|in sync| Pass["pass"]
CI -->|drift| Fail["fail<br/>(exit 1)"]

View File

@@ -0,0 +1,23 @@
%% MCP Server tool inventory by category
%% Reflects: open-sse/mcp-server/tools/* and docs/MCP-SERVER.md
%% v3.8.0
flowchart LR
MCP["MCP Server<br/>37 tools total"] --> Core["Core (30)"]
MCP --> Mem["Memory (3)"]
MCP --> Skl["Skills (4)"]
Core --> Essential["Essential (8)<br/>get_health, list_combos,<br/>switch_combo, check_quota,<br/>route_request, cost_report,<br/>list_models_catalog,<br/>get_combo_metrics"]
Core --> Search["Search (1)<br/>web_search"]
Core --> Advanced["Advanced (11)<br/>simulate_route, set_budget_guard,<br/>set_routing_strategy,<br/>set_resilience_profile,<br/>test_combo, get_provider_metrics,<br/>best_combo_for_task, explain_route,<br/>get_session_snapshot,<br/>db_health_check, sync_pricing"]
Core --> Cache["Cache (2)"]
Core --> Compression["Compression (5)"]
Core --> Tunnels["1Proxy / Tunnels (3)"]
Mem --> M1["memory_search"]
Mem --> M2["memory_save"]
Mem --> M3["memory_delete"]
Skl --> S1["skill_invoke"]
Skl --> S2["skill_list"]
Skl --> S3["skill_diagnose"]
Skl --> S4["skill_uninstall"]

View File

@@ -0,0 +1,24 @@
%% Request pipeline for /v1/chat/completions
%% Reflects: src/app/api/v1/chat/completions/route.ts → open-sse/handlers/chatCore.ts
%% v3.8.0
flowchart LR
Client["Client<br/>(IDE/CLI/SDK)"] --> Route["Next.js Route<br/>/v1/chat/completions"]
Route --> CORS["CORS preflight"]
CORS --> Validate["Zod validation<br/>(request body)"]
Validate --> Authz["AuthZ pipeline<br/>(extractApiKey +<br/>isValidApiKey)"]
Authz --> Policy["API key policy<br/>(allowlist + scopes)"]
Policy --> Guard["Prompt-injection<br/>guardrail"]
Guard --> ChatCore["handleChatCore"]
ChatCore --> Cache{"Cache hit?"}
Cache -->|yes| Return["Return cached"]
Cache -->|no| Rate["Rate limit<br/>(per-key, per-IP)"]
Rate --> Combo{"Combo<br/>target?"}
Combo -->|combo| Resolve["resolveComboTargets<br/>(14 strategies)"]
Resolve --> Single["handleSingleModel<br/>(per target)"]
Combo -->|single| Single
Single --> Translate["translateRequest<br/>(OpenAI↔Claude↔Gemini)"]
Translate --> Exec["getExecutor<br/>(31 executors)"]
Exec --> Upstream["Upstream Provider<br/>(177 providers)"]
Upstream --> Stream["SSE / JSON"]
Stream --> Transformer["responsesTransformer<br/>(Responses↔Chat)"]
Transformer --> Client

View File

@@ -0,0 +1,21 @@
%% 3-layer resilience model
%% Reflects: src/shared/utils/circuitBreaker.ts, src/sse/services/auth.ts,
%% open-sse/services/accountFallback.ts
%% v3.8.0
flowchart TB
Req["Request"] --> L1{"Provider Circuit Breaker<br/>(scope: whole provider)"}
L1 -->|CLOSED| L2
L1 -->|OPEN| Block1["Skip provider<br/>(or 503 retry-after)"]
L1 -->|HALF_OPEN| Probe["Allow probe"]
Probe --> L2
L2{"Connection Cooldown<br/>(scope: one account/key)"} -->|available| L3
L2 -->|cooling down| Skip2["Skip this connection<br/>fall back to next"]
L3{"Model Lockout<br/>(scope: provider × conn × model)"} -->|allowed| Exec["Execute upstream"]
L3 -->|locked| Skip3["Fall back to next model"]
Exec -->|success| Clear["Clear cooldowns/lockouts"]
Exec -->|"408 / 500 / 502 / 503 / 504"| TripL1["Trip provider breaker"]
Exec -->|"401 / 403 (account)"| TripL2["Start connection cooldown"]
Exec -->|"429 quota (model)"| TripL3["Start model lockout"]