|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Development Commands |
| 6 | + |
| 7 | +- **Build**: `bun run build` (uses tsdown) |
| 8 | +- **Development**: `bun run dev` (with file watching) |
| 9 | +- **Production**: `bun run start` (sets NODE_ENV=production) |
| 10 | +- **Lint**: `bun run lint` (uses @echristian/eslint-config with cache) |
| 11 | +- **Lint fix**: `bunx lint-staged` (fixes staged files) |
| 12 | +- **Typecheck**: `bun run typecheck` (runs TypeScript compiler) |
| 13 | +- **Test all**: `bun test` |
| 14 | +- **Test single file**: `bun test tests/[filename].test.ts` |
| 15 | +- **Package**: `bun run prepack` (builds before packaging) |
| 16 | + |
| 17 | +## Project Architecture |
| 18 | + |
| 19 | +### High-Level Structure |
| 20 | +This is a GitHub Copilot API proxy server that exposes Copilot as both OpenAI-compatible and Anthropic-compatible APIs. The server is built with Hono framework and uses Bun as the runtime. |
| 21 | + |
| 22 | +### Core Architecture Components |
| 23 | + |
| 24 | +**API Translation Layer** (`src/routes/messages/`): |
| 25 | +- Translates between Anthropic Messages API format and OpenAI Chat Completions format |
| 26 | +- Handles both streaming and non-streaming responses |
| 27 | +- Key files: `handler.ts`, `anthropic-types.ts`, `stream-translation.ts`, `non-stream-translation.ts` |
| 28 | + |
| 29 | +**Token Counting for Anthropic Models** (`src/lib/tokenizer.ts`): |
| 30 | +- Uses `gpt-tokenizer/model/gpt-4o` for token counting |
| 31 | +- Separates input tokens (all messages except last assistant message) from output tokens (last assistant message) |
| 32 | +- Filters out tool messages and extracts text content from multipart messages |
| 33 | +- Used by `/v1/messages/count_tokens` endpoint for Anthropic compatibility |
| 34 | + |
| 35 | +**GitHub Copilot Integration** (`src/services/`): |
| 36 | +- Authentication flow using device code OAuth |
| 37 | +- Token management and refresh |
| 38 | +- API requests to GitHub Copilot endpoints |
| 39 | +- Usage monitoring and quota tracking |
| 40 | + |
| 41 | +**Rate Limiting & Controls** (`src/lib/`): |
| 42 | +- Rate limiting between requests (`rate-limit.ts`) |
| 43 | +- Manual approval system for requests (`approval.ts`) |
| 44 | +- State management for server configuration (`state.ts`) |
| 45 | + |
| 46 | +### API Endpoints Structure |
| 47 | + |
| 48 | +**OpenAI Compatible**: |
| 49 | +- `/v1/chat/completions` - Chat completions |
| 50 | +- `/v1/models` - Available models |
| 51 | +- `/v1/embeddings` - Text embeddings |
| 52 | + |
| 53 | +**Anthropic Compatible**: |
| 54 | +- `/v1/messages` - Message completions (translates to/from OpenAI format) |
| 55 | +- `/v1/messages/count_tokens` - Token counting for Anthropic format |
| 56 | + |
| 57 | +**Monitoring**: |
| 58 | +- `/usage` - GitHub Copilot usage dashboard |
| 59 | +- `/token` - Current Copilot token info |
| 60 | + |
| 61 | +### Key Implementation Details |
| 62 | + |
| 63 | +**Anthropic Token Counting**: |
| 64 | +The `getTokenCount()` function in `src/lib/tokenizer.ts` implements token counting specifically for Anthropic compatibility: |
| 65 | +- Converts multipart content to text-only for counting |
| 66 | +- Splits messages into input (all except last assistant) and output (last assistant message only) |
| 67 | +- Uses GPT-4o tokenizer as the underlying counting mechanism |
| 68 | +- Returns `{input: number, output: number}` format |
| 69 | + |
| 70 | +**Message Translation**: |
| 71 | +- OpenAI → Anthropic: Converts chat completion responses to Anthropic message format |
| 72 | +- Anthropic → OpenAI: Converts Anthropic message requests to OpenAI chat completion format |
| 73 | +- Handles tool calls, system messages, and content blocks appropriately |
| 74 | + |
| 75 | +**Streaming Translation**: |
| 76 | +Real-time conversion of OpenAI SSE chunks to Anthropic streaming events, maintaining state for proper message reconstruction. |
| 77 | + |
| 78 | +## Code Style & Conventions |
| 79 | + |
| 80 | +- **TypeScript**: Strict mode enabled, avoid `any` types |
| 81 | +- **Imports**: Use `~/*` path aliases for `src/*` imports |
| 82 | +- **Error Handling**: Use explicit error classes from `src/lib/error.ts` |
| 83 | +- **Testing**: Place tests in `tests/` directory with `*.test.ts` naming |
| 84 | +- **Formatting**: Prettier with package.json plugin |
| 85 | +- **Linting**: @echristian/eslint-config with strict rules |
| 86 | + |
| 87 | +## Important Notes |
| 88 | + |
| 89 | +- Server uses GitHub Copilot as the underlying LLM provider |
| 90 | +- Rate limiting and manual approval features help avoid GitHub abuse detection |
| 91 | +- Token counting uses GPT-4o tokenizer regardless of the actual model being proxied |
| 92 | +- All API translations maintain compatibility with both OpenAI and Anthropic client libraries |
0 commit comments