mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
docs: enhance AGENTS.md with architecture internals and create CLAUDE.md (#1210)
Integrated into release/v3.6.5
This commit is contained in:
225
CLAUDE.md
Normal file
225
CLAUDE.md
Normal file
@@ -0,0 +1,225 @@
|
||||
# CLAUDE.md — AI Agent Session Bootstrap
|
||||
|
||||
> Quick-start context for AI coding agents. For deep architecture details, see `AGENTS.md`.
|
||||
> For contribution workflow, see `CONTRIBUTING.md`.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
npm install # Install deps (auto-generates .env from .env.example)
|
||||
npm run dev # Dev server at http://localhost:20128
|
||||
npm run build # Production build (Next.js 16 standalone)
|
||||
npm run lint # ESLint (0 errors expected; warnings are pre-existing)
|
||||
npm run typecheck:core # TypeScript check (should be clean)
|
||||
npm run test:coverage # Unit tests + coverage gate (60% min)
|
||||
npm run check # lint + test combined
|
||||
```
|
||||
|
||||
### Running a Single Test
|
||||
|
||||
```bash
|
||||
# Node.js native test runner (most tests)
|
||||
node --import tsx/esm --test tests/unit/your-file.test.mjs
|
||||
|
||||
# Vitest (MCP server, autoCombo, cache)
|
||||
npm run test:vitest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Project at a Glance
|
||||
|
||||
**OmniRoute** — unified AI proxy/router. One endpoint, 100+ LLM providers, auto-fallback.
|
||||
|
||||
| Layer | Location | Purpose |
|
||||
| --------------- | ------------------------ | ------------------------------------------ |
|
||||
| API Routes | `src/app/api/v1/` | Next.js App Router — entry points |
|
||||
| Handlers | `open-sse/handlers/` | Request processing (chat, embeddings, etc) |
|
||||
| Executors | `open-sse/executors/` | Provider-specific HTTP dispatch |
|
||||
| Translators | `open-sse/translator/` | Format conversion (OpenAI↔Claude↔Gemini) |
|
||||
| Services | `open-sse/services/` | Combo routing, rate limits, caching, etc |
|
||||
| Database | `src/lib/db/` | SQLite domain modules (22 files) |
|
||||
| Domain/Policy | `src/domain/` | Policy engine, cost rules, fallback logic |
|
||||
| MCP Server | `open-sse/mcp-server/` | 25 tools, 3 transports, 10 scopes |
|
||||
| A2A Server | `src/lib/a2a/` | JSON-RPC 2.0 agent protocol |
|
||||
| Skills | `src/lib/skills/` | Extensible skill framework |
|
||||
| Memory | `src/lib/memory/` | Persistent conversational memory |
|
||||
| UI Components | `src/shared/components/` | React components (Tailwind CSS v4) |
|
||||
| Provider Consts | `src/shared/constants/` | Provider registry (Zod-validated) |
|
||||
| Validation | `src/shared/validation/` | Zod v4 schemas |
|
||||
| Tests | `tests/` | Unit, integration, e2e, security, load |
|
||||
|
||||
### Monorepo Layout
|
||||
|
||||
```
|
||||
OmniRoute/ # Root package
|
||||
├── src/ # Next.js 16 app (TypeScript)
|
||||
├── open-sse/ # @omniroute/open-sse workspace (streaming engine)
|
||||
├── electron/ # Desktop app (Electron)
|
||||
├── tests/ # All test suites
|
||||
├── docs/ # Documentation
|
||||
└── bin/ # CLI entry point
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Request Pipeline (Abbreviated)
|
||||
|
||||
```
|
||||
Client → /v1/chat/completions (Next.js route)
|
||||
→ CORS → Zod validation → auth? → policy check → prompt injection guard
|
||||
→ handleChatCore() [open-sse/handlers/chatCore.ts]
|
||||
→ cache check → rate limit → combo routing?
|
||||
→ resolveComboTargets() → handleSingleModel() per target
|
||||
→ translateRequest() → getExecutor() → executor.execute()
|
||||
→ fetch() upstream → retry w/ backoff
|
||||
→ response translation → SSE stream or JSON
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Conventions
|
||||
|
||||
### Code Style
|
||||
|
||||
- **2 spaces**, semicolons, double quotes, 100 char width, es5 trailing commas
|
||||
- **Imports**: external → internal (`@/`, `@omniroute/open-sse`) → relative
|
||||
- **Naming**: files=camelCase/kebab, components=PascalCase, constants=UPPER_SNAKE
|
||||
|
||||
### Database Access
|
||||
|
||||
- **Always** go through `src/lib/db/` domain modules
|
||||
- **Never** write raw SQL in routes or handlers
|
||||
- **Never** add logic to `src/lib/localDb.ts` (re-export layer only)
|
||||
- **Never** barrel-import from `localDb.ts` — import specific `db/` modules
|
||||
- DB singleton: `getDbInstance()` from `src/lib/db/core.ts` (WAL journaling)
|
||||
- Migrations: `src/lib/db/migrations/` — 21 versioned SQL files
|
||||
|
||||
### Error Handling
|
||||
|
||||
- try/catch with specific error types, log with pino context
|
||||
- Never swallow errors in SSE streams — use abort signals
|
||||
- Return proper HTTP status codes (4xx/5xx)
|
||||
|
||||
### Security
|
||||
|
||||
- **Never** commit secrets/credentials
|
||||
- **Never** use `eval()`, `new Function()`, or implied eval
|
||||
- Validate all inputs with Zod schemas
|
||||
- Encrypt credentials at rest (AES-256-GCM)
|
||||
|
||||
---
|
||||
|
||||
## Common Modification Scenarios
|
||||
|
||||
### Adding a New Provider
|
||||
|
||||
1. Register in `src/shared/constants/providers.ts` (Zod-validated at load)
|
||||
2. Add executor in `open-sse/executors/` if custom logic needed
|
||||
3. Add translator in `open-sse/translator/` if non-OpenAI format
|
||||
4. Add OAuth config in `src/lib/oauth/constants/oauth.ts` if OAuth-based
|
||||
5. Register models in `open-sse/config/providerRegistry.ts`
|
||||
6. Write tests in `tests/unit/` (registration, translation, error handling)
|
||||
|
||||
### Adding a New API Route
|
||||
|
||||
1. Create directory under `src/app/api/v1/your-route/`
|
||||
2. Create `route.ts` with `GET`/`POST` handlers
|
||||
3. Follow pattern: CORS → Zod body validation → optional auth → handler delegation
|
||||
4. Handler goes in `open-sse/handlers/` (import from there, not inline)
|
||||
5. Add tests
|
||||
|
||||
### Adding a New DB Module
|
||||
|
||||
1. Create `src/lib/db/yourModule.ts`
|
||||
2. Import `getDbInstance` from `./core.ts`
|
||||
3. Export CRUD functions for your domain table(s)
|
||||
4. Add migration in `src/lib/db/migrations/` if new tables needed
|
||||
5. Re-export from `src/lib/localDb.ts` (add to the re-export list only)
|
||||
6. Write tests
|
||||
|
||||
### Adding a New MCP Tool
|
||||
|
||||
1. Add tool definition in `open-sse/mcp-server/tools/`
|
||||
2. Define Zod input schema + async handler
|
||||
3. Register in tool set (wired by `createMcpServer()`)
|
||||
4. Assign to appropriate scope(s)
|
||||
5. Write tests (tool invocation logged to `mcp_audit` table)
|
||||
|
||||
### Adding a New A2A Skill
|
||||
|
||||
1. Create skill in `src/lib/a2a/skills/`
|
||||
2. Skill receives task context (messages, metadata) → returns structured result
|
||||
3. Register in the DB-backed skill registry
|
||||
4. Write tests
|
||||
|
||||
---
|
||||
|
||||
## Testing Cheat Sheet
|
||||
|
||||
| What | Command |
|
||||
| ----------------------- | ------------------------------------------------------- |
|
||||
| All tests | `npm run test:all` |
|
||||
| Unit tests | `npm run test:unit` |
|
||||
| Single file | `node --import tsx/esm --test tests/unit/file.test.mjs` |
|
||||
| Vitest (MCP, autoCombo) | `npm run test:vitest` |
|
||||
| E2E (Playwright) | `npm run test:e2e` |
|
||||
| Protocol E2E (MCP+A2A) | `npm run test:protocols:e2e` |
|
||||
| Ecosystem | `npm run test:ecosystem` |
|
||||
| Coverage gate | `npm run test:coverage` (60% min all metrics) |
|
||||
| Coverage report | `npm run coverage:report` |
|
||||
|
||||
**PR rule**: If you change production code in `src/`, `open-sse/`, `electron/`, or `bin/`,
|
||||
you must include or update tests in the same PR.
|
||||
|
||||
---
|
||||
|
||||
## Git Workflow
|
||||
|
||||
```bash
|
||||
# Never commit directly to main
|
||||
git checkout -b feat/your-feature
|
||||
# ... make changes ...
|
||||
git commit -m "feat: describe your change"
|
||||
git push -u origin feat/your-feature
|
||||
```
|
||||
|
||||
**Branch prefixes**: `feat/`, `fix/`, `refactor/`, `docs/`, `test/`, `chore/`
|
||||
|
||||
**Commit format** ([Conventional Commits](https://www.conventionalcommits.org/)):
|
||||
|
||||
```
|
||||
feat: add circuit breaker for provider calls
|
||||
fix: resolve JWT secret validation edge case
|
||||
docs: update AGENTS.md with pipeline internals
|
||||
test: add MCP tool unit tests
|
||||
refactor(db): consolidate rate limit tables
|
||||
```
|
||||
|
||||
**Scopes**: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`,
|
||||
`memory`, `skills`.
|
||||
|
||||
---
|
||||
|
||||
## Environment
|
||||
|
||||
- **Runtime**: Node.js ≥18 <24, ES Modules
|
||||
- **TypeScript**: 5.9, target ES2022, module esnext, resolution bundler
|
||||
- **Path aliases**: `@/*` → `src/`, `@omniroute/open-sse` → `open-sse/`
|
||||
- **Default port**: 20128 (API + dashboard on same port)
|
||||
- **Data directory**: `DATA_DIR` env var, defaults to `~/.omniroute/`
|
||||
- **Key env vars**: `PORT`, `JWT_SECRET`, `INITIAL_PASSWORD`, `REQUIRE_API_KEY`, `APP_LOG_LEVEL`
|
||||
|
||||
---
|
||||
|
||||
## Hard Rules (Never Violate)
|
||||
|
||||
1. Never commit secrets or credentials
|
||||
2. Never add logic to `localDb.ts`
|
||||
3. Never use `eval()` / `new Function()` / implied eval
|
||||
4. Never commit directly to `main`
|
||||
5. Never write raw SQL in routes — use `src/lib/db/` modules
|
||||
6. Never silently swallow errors in SSE streams
|
||||
7. Always validate inputs with Zod schemas
|
||||
8. Always include tests when changing production code
|
||||
9. Coverage must stay ≥60% (statements, lines, functions, branches)
|
||||
Reference in New Issue
Block a user