{"id":49486447,"url":"https://github.com/skymoonsun/model-maestro","last_synced_at":"2026-05-01T02:01:56.619Z","repository":{"id":354925563,"uuid":"1080306090","full_name":"skymoonsun/model-maestro","owner":"skymoonsun","description":"Unified LLM Gateway that proxies multiple providers (Ollama, OpenAI-compatible) behind a single API. Enables IDEs and tools to access    multiple models via standard API formats. Manage LLM usage with per-user token limits, request logging, load balancing, model groups, and an admin dashboard.","archived":false,"fork":false,"pushed_at":"2026-05-01T00:33:15.000Z","size":780,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-01T01:13:41.646Z","etag":null,"topics":["ai","antigravity","claude-code","cursor","cursor-plugin","kiro","llm","model-maestro","ollama","openai-compatible","openclaw","orchestration","vllm"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/skymoonsun.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-21T07:16:59.000Z","updated_at":"2026-05-01T00:31:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/skymoonsun/model-maestro","commit_stats":null,"previous_names":["skymoonsun/model-maestro"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/skymoonsun/model-maestro","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skymoonsun%2Fmodel-maestro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skymoonsun%2Fmodel-maestro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skymoonsun%2Fmodel-maestro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skymoonsun%2Fmodel-maestro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skymoonsun","download_url":"https://codeload.github.com/skymoonsun/model-maestro/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skymoonsun%2Fmodel-maestro/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32482460,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","antigravity","claude-code","cursor","cursor-plugin","kiro","llm","model-maestro","ollama","openai-compatible","openclaw","orchestration","vllm"],"created_at":"2026-05-01T02:01:53.563Z","updated_at":"2026-05-01T02:01:56.607Z","avatar_url":"https://github.com/skymoonsun.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/assets/cover.png\" alt=\"Model Maestro\" width=\"720\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eConfig-driven Unified LLM Gateway\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  Route, load-balance and manage Ollama, OpenAI and other LLM providers through a single authenticated API.\n  Model Maestro gives you user-based access control, model mapping, token usage tracking, health-checked node pooling and a modern Next.js admin dashboard — all wired to PostgreSQL + Redis.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Python-3.11-blue?logo=python\u0026logoColor=white\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/FastAPI-0.109.0-009688?logo=fastapi\u0026logoColor=white\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Uvicorn-0.27.0-000000?logo=uvicorn\u0026logoColor=white\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/PostgreSQL-15-336791?logo=postgresql\u0026logoColor=white\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Redis-7-DC382D?logo=redis\u0026logoColor=white\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Next.js-16.1.6-000000?logo=next.js\u0026logoColor=white\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/React-19.2.3-61DAFB?logo=react\u0026logoColor=black\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Tailwind_CSS-v4-06B6D4?logo=tailwindcss\u0026logoColor=white\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Docker-2496ED?logo=docker\u0026logoColor=white\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"#quick-start\"\u003e\u003cstrong\u003eQuick Start\u003c/strong\u003e\u003c/a\u003e ·\n  \u003ca href=\"#features\"\u003e\u003cstrong\u003eFeatures\u003c/strong\u003e\u003c/a\u003e ·\n  \u003ca href=\"#architecture\"\u003e\u003cstrong\u003eArchitecture\u003c/strong\u003e\u003c/a\u003e ·\n  \u003ca href=\"#api-reference\"\u003e\u003cstrong\u003eAPI\u003c/strong\u003e\u003c/a\u003e ·\n  \u003ca href=\"#admin-panel\"\u003e\u003cstrong\u003eAdmin Panel\u003c/strong\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n\u003c!-- TOC --\u003e\n\n## Table of Contents\n\n- [Quick Start](#quick-start)\n- [Features](#features)\n- [Architecture](#architecture)\n- [Tech Stack](#tech-stack)\n- [Configuration](#configuration)\n- [Admin Panel](#admin-panel)\n- [API Reference](#api-reference)\n  - [Authentication](#authentication)\n  - [LLM Endpoints](#llm-endpoints)\n  - [Admin Endpoints](#admin-endpoints)\n  - [OpenAI Compatible](#openai-compatible)\n- [Model Mapping \u0026 Routing](#model-mapping--routing)\n- [Troubleshooting](#troubleshooting)\n- [Development](#development)\n- [License](#license)\n\n\u003c!-- /TOC --\u003e\n\n---\n\n## Quick Start\n\n\u003e Requires Docker \u0026 Docker Compose.\n\n```bash\n# 1. Clone\ngit clone \u003crepository-url\u003e \u0026\u0026 cd model-maestro\n\n# 2. Configure\ncp .env.example .env\n\n# 3. Launch full stack (PostgreSQL + Redis + FastAPI + Next.js)\ndocker compose -f docker-compose.dev.yml up --build -d\n\n# 4. Seed the database\ndocker exec maestro python -m app.seeder\n\n# 5. Open the admin panel at http://localhost:3000\n```\n\n| Service | URL | Notes |\n|---|---|---|\n| **API** | `http://localhost:8000` | FastAPI gateway |\n| **Admin Dashboard** | `http://localhost:3000` | Next.js admin panel |\n| **API Docs** | `http://localhost:8000/api/docs` | Basic-auth protected |\n\nFor a more detailed setup guide, see [`docs/SETUP.md`](docs/SETUP.md).\n\n---\n\n## Features\n\n- **JWT Authentication** — Bearer-token auth on every LLM request.\n- **Admin Dashboard** — Next.js 16 panel for visual management of users, nodes, models, groups and audit logs.\n- **Model Mapping** — Translate display names (`gpt-oss:120b`) to real names (`gpt-oss:120b-cloud`) via PostgreSQL with JSON-file caching.\n- **Multi-Node Load Balancing** — Round-robin, weighted and priority-based strategies across Ollama nodes.\n- **Model Groups** — Group models into logical units with fallback chains. Requests dynamically resolve to the best member based on capability tags (vision, tools) and strategy.\n- **Node Health Management** — Automatic health checks, model discovery and availability tracking.\n- **User-Level Access Control** — Per-user model allowlists and rate limits (requests / tokens per day).\n- **Token Usage Tracking** — Background-batched activity logs with prompt / completion / total token breakdowns.\n- **Tool Set Filtering** — Restrict which tools a model is allowed to invoke via configurable tool sets.\n- **Context Length Config** — Per-model context length stored in mappings (used by Cursor/Antigravity for usage bars).\n- **Streaming** — SSE-based streaming on `/api/chat`, `/api/generate` and `/v1/chat/completions`.\n- **OpenAI Compatible** — Drop-in `/v1/chat/completions` and `/v1/models` endpoints.\n- **Full Ollama API** — `/api/generate`, `/api/chat`, `/api/embeddings`, `/api/tags`, `/api/show`, `/api/copy`, `/api/delete`, `/api/pull`, `/api/push`, `/api/create`.\n- **DeepSeek Tool Call Parsing** — Auto-detects and converts DeepSeek's raw XML tool call output (`\u003ctool_calls\u003e\u003cinvoke\u003e`, `\u003cCallMcpTool\u003e`, `\u003ctool_call name=\"...\"\u003e`) to OpenAI `tool_calls` format in streaming and non-streaming responses. Kimi/Moonshot `\u003c|tool_calls_section_begin|\u003e` format also supported.\n- **Streaming-Aware Background Tasks** — Health checks, model discovery and warmup defer when streams are active, preventing interruptions.\n- **Node-Aware Model Warmup** — Warmup requests target only models that exist on each node, eliminating 404 errors from stale model names.\n- **Background Tasks** — Redis-backed async queue for activity logging, node health checks, model discovery, model warmup and load cleanup.\n- **Audit Logs** — Every admin action is timestamped and queryable.\n- **PostgreSQL + Alembic** — Schema migrations run automatically on container startup.\n- **Redis Cache** — Hot-path caching for mappings, config and user usage data.\n\n---\n\n## Architecture\n\n```\n┌──────────────┐     ┌──────────────┐     ┌──────────────┐\n│   Cursor     │     │  Antigravity │     │   Claude     │\n│   IDE        │     │   IDE        │     │   Code       │\n└──────┬───────┘     └──────┬───────┘     └──────┬───────┘\n       │                    │                    │\n       └────────────────────┼────────────────────┘\n                            │\n                     ┌──────┴──────┐\n                     │  Load       │\n                     │  Balancer   │\n                     └──────┬──────┘\n                            │\n       ┌────────────────────┼────────────────────┐\n       │                    │                    │\n┌──────┴──────┐    ┌────────┴────────┐   ┌──────┴──────┐\n│  Ollama     │    │    Ollama       │   │   OpenAI    │\n│  Node 1     │    │    Node 2       │   │   / Other   │\n└─────────────┘    └─────────────────┘   └─────────────┘\n```\n\n**Request Flow**\n\n```\nClient Request\n      │\n      ▼\n┌─────────────────┐\n│  JWT Middleware │\n└────────┬────────┘\n         │\n         ▼\n┌─────────────────┐\n│ Model Group?    │──No──▶┌──────────────┐\n│ (resolve member)│       │ Model Mapper │\n└────────┬────────┘       │ (display→real)│\n         │Yes             └──────┬───────┘\n         │                        │\n         ▼                        ▼\n┌─────────────────┐       ┌──────────────┐\n│ Load Balancer   │──────▶│ Node Pool    │\n│ (pick healthy)  │       │ (health check│\n└────────┬────────┘       │  + retry)    │\n         │                └──────┬───────┘\n         │                       │\n         ▼                       ▼\n┌─────────────────┐       ┌──────────────┐\n│ Ollama Proxy    │◀──────│ Ollama /     │\n│ (reverse map)   │       │ Provider API │\n└────────┬────────┘       └──────────────┘\n         │\n         ▼\n    Client Response\n```\n\nFor the full architecture documentation, see [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md).\n\n---\n\n## Tech Stack\n\n| Layer | Technology |\n|---|---|\n| **API Gateway** | Python 3.11, FastAPI, Uvicorn |\n| **Async HTTP** | httpx (HTTP/2) |\n| **Auth** | JWT (PyJWT) |\n| **Database** | PostgreSQL 15 + asyncpg + SQLAlchemy async |\n| **Migrations** | Alembic |\n| **Cache** | Redis 7 |\n| **Frontend** | Next.js 16, React 19, Tailwind CSS v4, shadcn/ui |\n| **Background Tasks** | Redis-backed async queue |\n| **Deployment** | Docker, Docker Compose |\n\n---\n\n## Configuration\n\nCopy `.env.example` to `.env` and set:\n\n```env\n# Ollama\nOLLAMA_BASE_URL=http://host.docker.internal:11434\nJWT_SECRET_KEY=change-this-to-a-strong-secret\nLOG_LEVEL=INFO\n\n# PostgreSQL\nDATABASE_URL=postgresql+asyncpg://maestro_user:maestro_password@postgres:5432/maestro\n\n# Redis\nREDIS_URL=redis://redis:6379/0\n\n# Admin Token (for /admin/* endpoints)\nADMIN_TOKEN=change-this-for-production\n\n# Admin Panel Login\nADMIN_USERNAME=admin\nADMIN_PASSWORD=admin\n\n# Swagger / ReDoc Basic Auth\nDOCS_USERNAME=admin\nDOCS_PASSWORD=admin\n```\n\n---\n\n## Admin Panel\n\nThe Next.js dashboard (`http://localhost:3000`) provides a visual interface for everything.\n\n| Page | What you can do |\n|---|---|\n| **Dashboard** | Node health, model counts, user statistics |\n| **Users** | Create users, manage tokens, assign models, set limits |\n| **Ollama \u003e Nodes** | Add/edit Ollama nodes, view health status, trigger discovery |\n| **Ollama \u003e Models** | Browse discovered models per node |\n| **Models \u003e Mappings** | Display↔Real name mappings, set context length, capabilities |\n| **Models \u003e Groups** | Create groups, add members, set strategy, reorder fallbacks |\n| **Models \u003e Config** | Per-model tool restrictions and settings |\n| **Tool Sets** | Create tool groups and assign to models |\n| **Settings** | System-wide configuration |\n| **Audit Logs** | Filterable history of all admin actions |\n\n**Default login:** username `admin`, password from `ADMIN_PASSWORD` in `.env`.\n\n---\n\n## API Reference\n\nFor the complete API reference with all request/response examples, see [`docs/API.md`](docs/API.md).\n\n### Authentication\n\nEvery LLM request requires:\n\n```\nAuthorization: Bearer \u003cjwt-token\u003e\n```\n\nAdmin endpoints require:\n\n```\nAuthorization: Bearer \u003cadmin-token\u003e\n```\n\n### LLM Endpoints\n\n| Method | Endpoint | Description |\n|---|---|---|\n| `POST` | `/api/chat` | Chat completions (Ollama format) |\n| `POST` | `/api/generate` | Text generation |\n| `POST` | `/api/embeddings` | Generate embeddings |\n| `GET`  | `/api/tags` | List available models |\n| `POST` | `/api/show` | Show model info |\n| `POST` | `/api/copy` | Copy model |\n| `DELETE`| `/api/delete` | Delete model |\n| `POST` | `/api/pull` | Pull model |\n| `POST` | `/api/push` | Push model |\n| `POST` | `/api/create` | Create model from Modelfile |\n\n**Example — Chat**\n\n```bash\ncurl -X POST http://localhost:8000/api/chat \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"model\": \"gpt-oss:120b\",\n    \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}],\n    \"stream\": false\n  }'\n```\n\n**Example — Streaming Chat**\n\n```bash\ncurl -X POST http://localhost:8000/api/chat \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"model\": \"gpt-oss:120b\",\n    \"messages\": [{\"role\": \"user\", \"content\": \"Tell me a story\"}],\n    \"stream\": true\n  }'\n```\n\n### Admin Endpoints\n\n**Users**\n\n```bash\n# Create user\ncurl -X POST http://localhost:8000/admin/users \\\n  -H \"Authorization: Bearer $ADMIN_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"username\": \"john\"}'\n\n# List users\ncurl http://localhost:8000/admin/users \\\n  -H \"Authorization: Bearer $ADMIN_TOKEN\"\n\n# Refresh token\ncurl -X PUT http://localhost:8000/admin/users/john/token \\\n  -H \"Authorization: Bearer $ADMIN_TOKEN\"\n```\n\n**Model Assignment**\n\n```bash\n# Assign specific models\ncurl -X POST http://localhost:8000/admin/users/john/models \\\n  -H \"Authorization: Bearer $ADMIN_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"models\": [\"gpt-oss:120b\", \"deepseek-v3.1:671b\"]}'\n\n# Grant access to all models\ncurl -X POST http://localhost:8000/admin/users/john/models/all \\\n  -H \"Authorization: Bearer $ADMIN_TOKEN\"\n```\n\n**User Limits**\n\n```bash\n# Set limits (null = unlimited)\ncurl -X POST http://localhost:8000/admin/users/john/limits \\\n  -H \"Authorization: Bearer $ADMIN_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"request_limit\": 1000, \"token_limit\": 1000000}'\n```\n\n**Model Mappings**\n\n```bash\n# Create mapping with context length\ncurl -X POST http://localhost:8000/admin/model-mappings \\\n  -H \"Authorization: Bearer $ADMIN_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"display_name\": \"gpt-oss:120b\",\n    \"real_name\": \"gpt-oss:120b-cloud\",\n    \"context_length\": 128000,\n    \"capabilities\": [\"completion\", \"tools\"]\n  }'\n\n# List\ncurl http://localhost:8000/admin/model-mappings \\\n  -H \"Authorization: Bearer $ADMIN_TOKEN\"\n\n# Delete\ncurl -X DELETE http://localhost:8000/admin/model-mappings/gpt-oss:120b \\\n  -H \"Authorization: Bearer $ADMIN_TOKEN\"\n```\n\n**Nodes**\n\n```bash\n# Add node\ncurl -X POST http://localhost:8000/admin/nodes \\\n  -H \"Authorization: Bearer $ADMIN_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\": \"main\", \"base_url\": \"http://localhost:11434\", \"priority\": 100}'\n\n# Toggle activation\ncurl -X PATCH http://localhost:8000/admin/nodes/1/toggle \\\n  -H \"Authorization: Bearer $ADMIN_TOKEN\"\n```\n\n**Model Groups**\n\n```bash\n# Create group\ncurl -X POST http://localhost:8000/admin/model-groups \\\n  -H \"Authorization: Bearer $ADMIN_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\": \"coding\", \"strategy\": \"round_robin\", \"description\": \"Code models\"}'\n\n# Add member\ncurl -X POST http://localhost:8000/admin/model-groups/coding/members \\\n  -H \"Authorization: Bearer $ADMIN_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model_display_name\": \"qwen3-coder:480b\", \"priority\": 1}'\n```\n\n### OpenAI Compatible\n\n| Method | Endpoint | Description |\n|---|---|---|\n| `POST` | `/v1/chat/completions` | Chat completions (OpenAI format) |\n| `GET`  | `/v1/models` | Model list (OpenAI format) |\n\n**Example — OpenAI Compatible**\n\n```bash\ncurl -X POST http://localhost:8000/v1/chat/completions \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"model\": \"gpt-oss:120b\",\n    \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}],\n    \"stream\": true\n  }'\n```\n\n---\n\n## Model Mapping \u0026 Routing\n\n**Display Name → Real Name**\n\n```\nClient sends:       gpt-oss:120b\nProxy looks up:     gpt-oss:120b → gpt-oss:120b-cloud\nOllama receives:    gpt-oss:120b-cloud\n```\n\n**Real Name → Display Name**\n\n```\nOllama returns:     gpt-oss:120b-cloud\nProxy translates:   gpt-oss:120b-cloud → gpt-oss:120b\nClient sees:        gpt-oss:120b\n```\n\n**Model Groups**\n\nIf the requested model is a group, the gateway resolves it dynamically:\n\n1. Detect if the request needs vision (image content in messages).\n2. Filter members by capability tags (`vision`, `tools`).\n3. Pick a member using the group's strategy:\n   - `round_robin` — cycle through members\n   - `weighted` — weighted random selection\n   - `priority` — always pick lowest priority number\n4. If the selected model fails, retry with the next member in priority order.\n\n---\n\n## Troubleshooting\n\n**Restart the full stack**\n\n```bash\ndocker compose -f docker-compose.dev.yml down\ndocker compose -f docker-compose.dev.yml up --build -d\n```\n\n**Run migrations manually**\n\n```bash\ndocker exec maestro alembic upgrade head\n```\n\n**Re-run seeds**\n\n```bash\ndocker exec maestro python -m app.seeder --reset\ndocker exec maestro python -m app.seeder\n```\n\n**Clear cache**\n\n```bash\ndocker exec maestro python scripts/clear_cache.py\n```\n\n**Check PostgreSQL health**\n\n```bash\ndocker exec maestro-postgres pg_isready -U maestro_user -d maestro\n```\n\n**Check Redis**\n\n```bash\ndocker exec maestro-redis redis-cli ping\n```\n\n**View logs**\n\n```bash\n# All services\ndocker compose -f docker-compose.dev.yml logs -f\n\n# API only\ndocker compose -f docker-compose.dev.yml logs -f maestro\n\n# Frontend only\ndocker compose -f docker-compose.dev.yml logs -f frontend\n```\n\n---\n\n## Development\n\n### Project Structure\n\n```\nmodel-maestro/\n├── app/\n│   ├── main.py              # FastAPI app, routers, docs auth\n│   ├── proxy.py             # Proxy logic, model routing, failover, tool call parsing\n│   ├── config.py            # Settings, ModelMappingManager, ModelGroupManager\n│   ├── auth.py              # JWT authentication\n│   ├── models.py            # Pydantic request/response models\n│   ├── models_db.py         # SQLAlchemy ORM models\n│   ├── database.py          # Async DB engine \u0026 session maker\n│   ├── redis.py             # Redis client \u0026 queue\n│   ├── load_balancer.py     # Node selection algorithms\n│   ├── node_manager.py      # Health checks, discovery, node CRUD\n│   ├── user_manager.py      # User CRUD\n│   ├── background_tasks.py  # Activity log processor, health checks, model warmup\n│   ├── openclaw.py          # OpenClaw integration\n│   ├── admin*.py            # Admin API routers\n│   ├── repositories/        # Data access layer\n│   ├── services/            # Business logic layer\n│   └── seeds/               # DB seed migrations\n├── frontend/\n│   ├── src/app/             # Next.js App Router pages\n│   ├── src/components/      # React components (sidebar, shell, etc.)\n│   └── public/              # Static assets (logo, favicon)\n├── docs/                    # Documentation (architecture, API, setup)\n├── alembic/                 # Alembic migrations\n├── tests/                   # pytest suite\n├── docker-compose.dev.yml   # Dev stack (PG + Redis + API + Frontend)\n├── docker-compose.yml       # Production stack (API + Frontend only)\n└── Dockerfile               # FastAPI container\n```\n\n### Running Tests\n\n```bash\npython -m pytest tests/ -v\n```\n\n### Lint \u0026 Format\n\n```bash\n# Backend\npython -m black app/\npython -m ruff check app/\n\n# Frontend\ncd frontend \u0026\u0026 npm run lint\n```\n\n---\n\n## Documentation\n\n- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — System architecture, request flow, database schema\n- [`docs/API.md`](docs/API.md) — Complete API reference with all endpoints, requests and responses\n- [`docs/SETUP.md`](docs/SETUP.md) — Detailed setup guide, environment variables, production deployment\n- [`QUICKSTART.md`](QUICKSTART.md) — Get running in under 5 minutes\n\n---\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskymoonsun%2Fmodel-maestro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskymoonsun%2Fmodel-maestro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskymoonsun%2Fmodel-maestro/lists"}