this repo has no description
1/**
2 * Auth adapter proxy for anthropic-proxy
3 *
4 * Translates Authorization: Bearer <token> to x-api-key: <token>
5 * This allows Letta (which uses OpenAI-style auth) to communicate
6 * with anthropic-proxy (which expects x-api-key header).
7 *
8 * Run: bun src/auth-adapter.ts
9 */
10
11const PROXY_TARGET = process.env['ANTHROPIC_PROXY_INTERNAL_URL'] ?? 'http://localhost:4001';
12const PORT = Number(process.env['AUTH_ADAPTER_PORT'] ?? '4002');
13
14console.log(`Auth adapter starting on port ${PORT.toString()}`);
15console.log(`Proxying to: ${PROXY_TARGET}`);
16
17Bun.serve({
18 port: PORT,
19 async fetch(req) {
20 const url = new URL(req.url);
21 const targetUrl = `${PROXY_TARGET}${url.pathname}${url.search}`;
22
23 console.log(`[${req.method}] ${url.pathname}`);
24
25 // Clone headers and translate auth
26 const headers = new Headers(req.headers);
27
28 // Extract Bearer token and convert to x-api-key
29 // Also handle case where LiteLLM sends x-api-key directly (for Anthropic provider)
30 const authHeader = headers.get('Authorization') ?? '';
31 if (authHeader.startsWith('Bearer ')) {
32 const token = authHeader.slice(7);
33 headers.set('x-api-key', token);
34 headers.delete('Authorization');
35 }
36 // If x-api-key is already set (by LiteLLM's Anthropic provider), it passes through
37
38 // Request uncompressed responses (Letta can't handle gzip)
39 headers.set('Accept-Encoding', 'identity');
40
41 // Forward the request
42 try {
43 const response = await fetch(targetUrl, {
44 method: req.method,
45 headers,
46 body: req.method !== 'GET' && req.method !== 'HEAD' ? req.body : undefined,
47 });
48
49 console.log(` Response: ${response.status.toString()}`);
50
51 // Return the response
52 return new Response(response.body, {
53 status: response.status,
54 statusText: response.statusText,
55 headers: response.headers,
56 });
57 } catch (error) {
58 console.error('Proxy error:', error);
59 return new Response(JSON.stringify({ error: 'Proxy error' }), {
60 status: 502,
61 headers: { 'Content-Type': 'application/json' },
62 });
63 }
64 },
65});
66
67console.log(`Auth adapter listening on http://localhost:${PORT.toString()}`);