|
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 OpenAI-compatible, Anthropic-compatible, and Gemini-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 | | -- Translates between Gemini API format and OpenAI Chat Completions format |
27 | | -- Handles both streaming and non-streaming responses |
28 | | -- Key files: `handler.ts`, `anthropic-types.ts`, `stream-translation.ts`, `non-stream-translation.ts` |
29 | | -- Gemini files: `gemini-handler.ts`, `gemini-translation.ts`, `gemini-types.ts`, `gemini-route.ts` |
30 | | - |
31 | | -**Token Counting for Anthropic Models** (`src/lib/tokenizer.ts`): |
32 | | -- Uses `gpt-tokenizer/model/gpt-4o` for token counting |
33 | | -- Separates input tokens (all messages except last assistant message) from output tokens (last assistant message) |
34 | | -- Filters out tool messages and extracts text content from multipart messages |
35 | | -- Used by `/v1/messages/count_tokens` endpoint for Anthropic compatibility |
36 | | - |
37 | | -**GitHub Copilot Integration** (`src/services/`): |
38 | | -- Authentication flow using device code OAuth |
39 | | -- Token management and refresh |
40 | | -- API requests to GitHub Copilot endpoints |
41 | | -- Usage monitoring and quota tracking |
42 | | - |
43 | | -**Rate Limiting & Controls** (`src/lib/`): |
44 | | -- Rate limiting between requests (`rate-limit.ts`) |
45 | | -- Manual approval system for requests (`approval.ts`) |
46 | | -- State management for server configuration (`state.ts`) |
47 | | - |
48 | | -### API Endpoints Structure |
49 | | - |
50 | | -**OpenAI Compatible**: |
51 | | -- `/v1/chat/completions` - Chat completions |
52 | | -- `/v1/models` - Available models |
53 | | -- `/v1/embeddings` - Text embeddings |
54 | | - |
55 | | -**Anthropic Compatible**: |
56 | | -- `/v1/messages` - Message completions (translates to/from OpenAI format) |
57 | | -- `/v1/messages/count_tokens` - Token counting for Anthropic format |
58 | | - |
59 | | -**Gemini Compatible**: |
60 | | -- `/v1beta/models/{model}:generateContent` - Standard generation |
61 | | -- `/v1beta/models/{model}:streamGenerateContent` - Streaming generation |
62 | | -- `/v1beta/models/{model}:countTokens` - Token counting |
63 | | - |
64 | | -**Monitoring**: |
65 | | -- `/usage` - GitHub Copilot usage dashboard |
66 | | -- `/token` - Current Copilot token info |
67 | | - |
68 | | -### Key Implementation Details |
69 | | - |
70 | | -**Anthropic Token Counting**: |
71 | | -The `getTokenCount()` function in `src/lib/tokenizer.ts` implements token counting specifically for Anthropic compatibility: |
72 | | -- Converts multipart content to text-only for counting |
73 | | -- Splits messages into input (all except last assistant) and output (last assistant message only) |
74 | | -- Uses GPT-4o tokenizer as the underlying counting mechanism |
75 | | -- Returns `{input: number, output: number}` format |
76 | | - |
77 | | -**Message Translation**: |
78 | | -- OpenAI → Anthropic: Converts chat completion responses to Anthropic message format |
79 | | -- Anthropic → OpenAI: Converts Anthropic message requests to OpenAI chat completion format |
80 | | -- OpenAI → Gemini: Converts chat completion responses to Gemini response format |
81 | | -- Gemini → OpenAI: Converts Gemini requests to OpenAI chat completion format |
82 | | -- Handles tool calls, system messages, and content blocks appropriately for all formats |
83 | | - |
84 | | -**Streaming Translation**: |
85 | | -Real-time conversion of OpenAI SSE chunks to both Anthropic streaming events and Gemini streaming responses, maintaining state for proper message reconstruction. |
86 | | - |
87 | | -**Gemini API Implementation**: |
88 | | -The Gemini integration (`src/routes/messages/gemini-*`) provides: |
89 | | -- Full compatibility with Google's Gemini API specification |
90 | | -- Comprehensive request/response translation between Gemini and OpenAI formats |
91 | | -- Support for function calling, multimodal content (text + images), and streaming |
92 | | -- Extensive debug logging with file-based logs in `logs/` directory |
93 | | -- Error handling with appropriate HTTP status codes and Gemini-formatted error responses |
94 | | -- Support for generation configuration (temperature, max tokens, top-p, stop sequences) |
95 | | - |
96 | | -**Critical Gemini Translation Details**: |
97 | | -- Gemini CLI sends function responses as **nested arrays** in contents, requiring special handling |
98 | | -- `parametersJsonSchema` field takes precedence over `parameters` in function declarations |
99 | | -- Tool call ID mapping must be maintained between assistant tool calls and user tool responses |
100 | | -- Function response arrays need extraction with `processFunctionResponseArray()` helper |
101 | | -- Debug logs in `logs/gemini-*.log` files are essential for troubleshooting translation issues |
102 | | - |
103 | | -## Code Style & Conventions |
104 | | - |
105 | | -- **TypeScript**: Strict mode enabled, avoid `any` types |
106 | | -- **Imports**: Use `~/*` path aliases for `src/*` imports |
107 | | -- **Error Handling**: Use explicit error classes from `src/lib/error.ts` |
108 | | -- **Testing**: Place tests in `tests/` directory with `*.test.ts` naming |
109 | | -- **Formatting**: Prettier with package.json plugin |
110 | | -- **Linting**: @echristian/eslint-config with strict rules |
111 | | - |
112 | | -## Important Notes |
113 | | - |
114 | | -- Server uses GitHub Copilot as the underlying LLM provider |
115 | | -- Rate limiting and manual approval features help avoid GitHub abuse detection |
116 | | -- Token counting uses GPT-4o tokenizer regardless of the actual model being proxied |
117 | | -- All API translations maintain compatibility with OpenAI, Anthropic, and Gemini client libraries |
118 | | -- Gemini API debugging logs are written to `logs/` directory for troubleshooting translation issues |
119 | | - |
120 | | -## Debugging & Troubleshooting |
121 | | - |
122 | | -**Common Gemini API Issues**: |
123 | | -- **Function calls fail while text prompts work**: Check `logs/gemini-translation.log` for missing `parameters` in translated tools |
124 | | -- **Tool response mapping errors**: Verify tool_call_id consistency between assistant tool calls and user tool responses |
125 | | -- **Nested array handling**: Gemini CLI sends function responses as nested arrays requiring `processFunctionResponseArray()` extraction |
126 | | -- **HTTPError from create-chat-completions**: Usually indicates parameter validation failure in OpenAI translation layer |
127 | | - |
128 | | -**Key Log Files**: |
129 | | -- `logs/gemini-errors.log`: HTTP errors and stack traces |
130 | | -- `logs/gemini-debug.log`: Request/response flow with full JSON payloads |
131 | | -- `logs/gemini-translation.log`: Translation pipeline details showing input/output transformations |
132 | | - |
133 | | -**Debugging Commands**: |
134 | | -- `bun run lint && bun run typecheck && bun run build`: Full validation pipeline |
135 | | -- Check error reports in `C:\Users\39764\AppData\Local\Temp\gemini-client-error-*.json` for client-side failures |
0 commit comments