@relayplane/proxy 0.2.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.js ADDED
@@ -0,0 +1,637 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * RelayPlane Local LLM Proxy Server
4
+ *
5
+ * Routes OpenAI-compatible requests to multiple providers.
6
+ * Features:
7
+ * - /health endpoint for monitoring
8
+ * - Usage tracking with spending warnings
9
+ * - Model aliases (rp:fast, rp:cheap, rp:best)
10
+ * - Dry-run mode for testing
11
+ */
12
+ import * as http from 'http';
13
+ import * as https from 'https';
14
+ import * as fs from 'fs';
15
+ import * as path from 'path';
16
+ import * as os from 'os';
17
+ const VERSION = '1.1.0';
18
+ const startTime = Date.now();
19
+ // Configuration
20
+ const PORT = parseInt(process.env.RELAYPLANE_PROXY_PORT || '8787', 10);
21
+ const HOST = process.env.RELAYPLANE_PROXY_HOST || '127.0.0.1';
22
+ const CONFIG_DIR = process.env.RELAYPLANE_CONFIG_DIR || path.join(os.homedir(), '.relayplane');
23
+ const stats = {
24
+ requestsHandled: 0,
25
+ requestsSuccessful: 0,
26
+ requestsFailed: 0,
27
+ totalInputTokens: 0,
28
+ totalOutputTokens: 0,
29
+ totalCost: 0,
30
+ byModel: new Map(),
31
+ byProvider: new Map(),
32
+ };
33
+ /**
34
+ * Model alias mappings
35
+ */
36
+ const MODEL_ALIASES = {
37
+ 'rp:fast': { model: 'llama-3.1-8b-instant', provider: 'groq' },
38
+ 'rp:cheap': { model: 'llama-3.1-8b-instant', provider: 'groq' },
39
+ 'rp:best': { model: 'claude-3-5-sonnet-20241022', provider: 'anthropic' },
40
+ 'rp:balanced': { model: 'gpt-4o-mini', provider: 'openai' },
41
+ };
42
+ const PROVIDERS = {
43
+ openai: {
44
+ baseUrl: 'https://api.openai.com',
45
+ apiKeyEnv: 'OPENAI_API_KEY',
46
+ headerName: 'Authorization',
47
+ headerPrefix: 'Bearer ',
48
+ },
49
+ anthropic: {
50
+ baseUrl: 'https://api.anthropic.com',
51
+ apiKeyEnv: 'ANTHROPIC_API_KEY',
52
+ headerName: 'x-api-key',
53
+ headerPrefix: '',
54
+ extraHeaders: {
55
+ 'anthropic-version': '2023-06-01',
56
+ },
57
+ },
58
+ groq: {
59
+ baseUrl: 'https://api.groq.com/openai',
60
+ apiKeyEnv: 'GROQ_API_KEY',
61
+ headerName: 'Authorization',
62
+ headerPrefix: 'Bearer ',
63
+ },
64
+ together: {
65
+ baseUrl: 'https://api.together.xyz',
66
+ apiKeyEnv: 'TOGETHER_API_KEY',
67
+ headerName: 'Authorization',
68
+ headerPrefix: 'Bearer ',
69
+ },
70
+ openrouter: {
71
+ baseUrl: 'https://openrouter.ai/api',
72
+ apiKeyEnv: 'OPENROUTER_API_KEY',
73
+ headerName: 'Authorization',
74
+ headerPrefix: 'Bearer ',
75
+ },
76
+ };
77
+ /**
78
+ * Model to provider mapping (simplified)
79
+ */
80
+ function detectProvider(model) {
81
+ if (model.startsWith('gpt-') || model.startsWith('o1-'))
82
+ return 'openai';
83
+ if (model.startsWith('claude-'))
84
+ return 'anthropic';
85
+ if (model.startsWith('llama-') || model.startsWith('mixtral-'))
86
+ return 'groq';
87
+ if (model.startsWith('meta-llama/') || model.startsWith('mistralai/'))
88
+ return 'together';
89
+ if (model.includes('/'))
90
+ return 'openrouter';
91
+ return 'openai'; // Default fallback
92
+ }
93
+ /**
94
+ * Track which warnings we've already logged to avoid spam
95
+ */
96
+ const loggedWarnings = {
97
+ daily80: false,
98
+ daily90: false,
99
+ daily100: false,
100
+ monthly80: false,
101
+ monthly90: false,
102
+ monthly100: false,
103
+ };
104
+ function loadConfig() {
105
+ const configPath = path.join(CONFIG_DIR, 'config.json');
106
+ try {
107
+ if (fs.existsSync(configPath)) {
108
+ return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
109
+ }
110
+ }
111
+ catch {
112
+ // Ignore errors
113
+ }
114
+ return null;
115
+ }
116
+ function loadDailyUsage() {
117
+ const today = new Date().toISOString().split('T')[0];
118
+ const usagePath = path.join(CONFIG_DIR, 'daily-usage.json');
119
+ try {
120
+ if (fs.existsSync(usagePath)) {
121
+ const data = JSON.parse(fs.readFileSync(usagePath, 'utf-8'));
122
+ if (data.date === today) {
123
+ return data;
124
+ }
125
+ }
126
+ }
127
+ catch {
128
+ // Ignore errors
129
+ }
130
+ return { date: today, cost: 0, requests: 0 };
131
+ }
132
+ /**
133
+ * Save daily usage to file
134
+ */
135
+ function saveDailyUsage(usage) {
136
+ const usagePath = path.join(CONFIG_DIR, 'daily-usage.json');
137
+ try {
138
+ if (!fs.existsSync(CONFIG_DIR)) {
139
+ fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
140
+ }
141
+ fs.writeFileSync(usagePath, JSON.stringify(usage, null, 2));
142
+ }
143
+ catch {
144
+ // Ignore errors
145
+ }
146
+ }
147
+ function loadMonthlyUsage() {
148
+ const currentMonth = new Date().toISOString().slice(0, 7); // YYYY-MM
149
+ const usagePath = path.join(CONFIG_DIR, 'monthly-usage.json');
150
+ try {
151
+ if (fs.existsSync(usagePath)) {
152
+ const data = JSON.parse(fs.readFileSync(usagePath, 'utf-8'));
153
+ if (data.month === currentMonth) {
154
+ return data;
155
+ }
156
+ }
157
+ }
158
+ catch {
159
+ // Ignore errors
160
+ }
161
+ return { month: currentMonth, cost: 0, requests: 0 };
162
+ }
163
+ function saveMonthlyUsage(usage) {
164
+ const usagePath = path.join(CONFIG_DIR, 'monthly-usage.json');
165
+ try {
166
+ if (!fs.existsSync(CONFIG_DIR)) {
167
+ fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
168
+ }
169
+ fs.writeFileSync(usagePath, JSON.stringify(usage, null, 2));
170
+ }
171
+ catch {
172
+ // Ignore errors
173
+ }
174
+ }
175
+ /**
176
+ * Check spending limits and log warnings
177
+ */
178
+ function checkAndWarnLimits(dailyUsage, monthlyUsage, config) {
179
+ const warnings = [];
180
+ // Check daily limits
181
+ if (config?.limits?.daily) {
182
+ const dailyPercent = (dailyUsage.cost / config.limits.daily) * 100;
183
+ if (dailyPercent >= 100 && !loggedWarnings.daily100) {
184
+ console.warn(`⚠️ DAILY LIMIT REACHED: $${dailyUsage.cost.toFixed(2)} / $${config.limits.daily} (100%)`);
185
+ loggedWarnings.daily100 = true;
186
+ warnings.push(`Daily limit reached: $${dailyUsage.cost.toFixed(2)} of $${config.limits.daily}`);
187
+ }
188
+ else if (dailyPercent >= 90 && !loggedWarnings.daily90) {
189
+ console.warn(`⚠️ Daily spending at 90%: $${dailyUsage.cost.toFixed(2)} / $${config.limits.daily}`);
190
+ loggedWarnings.daily90 = true;
191
+ warnings.push(`⚠️ You've used $${dailyUsage.cost.toFixed(2)} of your $${config.limits.daily} daily limit`);
192
+ }
193
+ else if (dailyPercent >= 80 && !loggedWarnings.daily80) {
194
+ console.warn(`⚠️ Daily spending at 80%: $${dailyUsage.cost.toFixed(2)} / $${config.limits.daily}`);
195
+ loggedWarnings.daily80 = true;
196
+ warnings.push(`⚠️ You've used $${dailyUsage.cost.toFixed(2)} of your $${config.limits.daily} daily limit`);
197
+ }
198
+ }
199
+ // Check monthly limits
200
+ if (config?.limits?.monthly) {
201
+ const monthlyPercent = (monthlyUsage.cost / config.limits.monthly) * 100;
202
+ if (monthlyPercent >= 100 && !loggedWarnings.monthly100) {
203
+ console.warn(`⚠️ MONTHLY LIMIT REACHED: $${monthlyUsage.cost.toFixed(2)} / $${config.limits.monthly} (100%)`);
204
+ loggedWarnings.monthly100 = true;
205
+ warnings.push(`Monthly limit reached: $${monthlyUsage.cost.toFixed(2)} of $${config.limits.monthly}`);
206
+ }
207
+ else if (monthlyPercent >= 90 && !loggedWarnings.monthly90) {
208
+ console.warn(`⚠️ Monthly spending at 90%: $${monthlyUsage.cost.toFixed(2)} / $${config.limits.monthly}`);
209
+ loggedWarnings.monthly90 = true;
210
+ warnings.push(`⚠️ You've used $${monthlyUsage.cost.toFixed(2)} of your $${config.limits.monthly} monthly limit`);
211
+ }
212
+ else if (monthlyPercent >= 80 && !loggedWarnings.monthly80) {
213
+ console.warn(`⚠️ Monthly spending at 80%: $${monthlyUsage.cost.toFixed(2)} / $${config.limits.monthly}`);
214
+ loggedWarnings.monthly80 = true;
215
+ warnings.push(`⚠️ You've used $${monthlyUsage.cost.toFixed(2)} of your $${config.limits.monthly} monthly limit`);
216
+ }
217
+ }
218
+ return warnings.length > 0 ? warnings.join('; ') : null;
219
+ }
220
+ /**
221
+ * Log usage to JSONL file
222
+ */
223
+ function logUsage(record) {
224
+ const usagePath = path.join(CONFIG_DIR, 'usage.jsonl');
225
+ try {
226
+ if (!fs.existsSync(CONFIG_DIR)) {
227
+ fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
228
+ }
229
+ fs.appendFileSync(usagePath, JSON.stringify(record) + '\n');
230
+ }
231
+ catch {
232
+ // Ignore errors
233
+ }
234
+ }
235
+ /**
236
+ * Estimate cost for a request (simplified pricing)
237
+ */
238
+ function estimateCost(model, inputTokens, outputTokens) {
239
+ // Simplified pricing per 1M tokens
240
+ const pricing = {
241
+ 'gpt-4o': { input: 5.0, output: 15.0 },
242
+ 'gpt-4o-mini': { input: 0.15, output: 0.6 },
243
+ 'gpt-4-turbo': { input: 10.0, output: 30.0 },
244
+ 'gpt-3.5-turbo': { input: 0.5, output: 1.5 },
245
+ 'claude-3-5-sonnet-20241022': { input: 3.0, output: 15.0 },
246
+ 'claude-3-opus-20240229': { input: 15.0, output: 75.0 },
247
+ 'claude-3-haiku-20240307': { input: 0.25, output: 1.25 },
248
+ 'llama-3.1-8b-instant': { input: 0.05, output: 0.08 },
249
+ 'llama-3.1-70b-versatile': { input: 0.59, output: 0.79 },
250
+ 'mixtral-8x7b-32768': { input: 0.24, output: 0.24 },
251
+ };
252
+ const price = pricing[model] || { input: 1.0, output: 2.0 };
253
+ return (inputTokens / 1_000_000) * price.input + (outputTokens / 1_000_000) * price.output;
254
+ }
255
+ /**
256
+ * Parse request body
257
+ */
258
+ async function parseBody(req) {
259
+ return new Promise((resolve, reject) => {
260
+ let body = '';
261
+ req.on('data', chunk => (body += chunk.toString()));
262
+ req.on('end', () => resolve(body));
263
+ req.on('error', reject);
264
+ });
265
+ }
266
+ /**
267
+ * Send JSON response
268
+ */
269
+ function sendJson(res, status, data) {
270
+ res.writeHead(status, {
271
+ 'Content-Type': 'application/json',
272
+ 'Access-Control-Allow-Origin': '*',
273
+ 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
274
+ 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Dry-Run',
275
+ });
276
+ res.end(JSON.stringify(data));
277
+ }
278
+ /**
279
+ * Get provider configuration status
280
+ */
281
+ function getProviderStatus() {
282
+ const providerStatus = {};
283
+ for (const [name, config] of Object.entries(PROVIDERS)) {
284
+ const apiKey = process.env[config.apiKeyEnv];
285
+ providerStatus[name] = apiKey ? 'configured' : 'not_configured';
286
+ }
287
+ return providerStatus;
288
+ }
289
+ /**
290
+ * Handle /health endpoint
291
+ */
292
+ function handleHealth(res) {
293
+ const config = loadConfig();
294
+ const dailyUsage = loadDailyUsage();
295
+ const monthlyUsage = loadMonthlyUsage();
296
+ const health = {
297
+ status: 'ok',
298
+ uptime: Math.floor((Date.now() - startTime) / 1000),
299
+ version: VERSION,
300
+ providers: getProviderStatus(),
301
+ requestsHandled: stats.requestsHandled,
302
+ requestsSuccessful: stats.requestsSuccessful,
303
+ requestsFailed: stats.requestsFailed,
304
+ dailyCost: dailyUsage.cost,
305
+ dailyLimit: config?.limits?.daily,
306
+ monthlyCost: monthlyUsage.cost,
307
+ monthlyLimit: config?.limits?.monthly,
308
+ usage: {
309
+ inputTokens: stats.totalInputTokens,
310
+ outputTokens: stats.totalOutputTokens,
311
+ totalCost: stats.totalCost,
312
+ },
313
+ };
314
+ sendJson(res, 200, health);
315
+ }
316
+ /**
317
+ * Handle /v1/models endpoint
318
+ */
319
+ function handleModels(res) {
320
+ const models = [
321
+ // OpenAI
322
+ { id: 'gpt-4o', provider: 'openai', alias: null },
323
+ { id: 'gpt-4o-mini', provider: 'openai', alias: 'rp:balanced' },
324
+ { id: 'gpt-4-turbo', provider: 'openai', alias: null },
325
+ { id: 'gpt-3.5-turbo', provider: 'openai', alias: null },
326
+ // Anthropic
327
+ { id: 'claude-3-5-sonnet-20241022', provider: 'anthropic', alias: 'rp:best' },
328
+ { id: 'claude-3-opus-20240229', provider: 'anthropic', alias: null },
329
+ { id: 'claude-3-haiku-20240307', provider: 'anthropic', alias: null },
330
+ // Groq
331
+ { id: 'llama-3.1-70b-versatile', provider: 'groq', alias: null },
332
+ { id: 'llama-3.1-8b-instant', provider: 'groq', alias: 'rp:fast, rp:cheap' },
333
+ { id: 'mixtral-8x7b-32768', provider: 'groq', alias: null },
334
+ // Aliases
335
+ { id: 'rp:fast', provider: 'groq', alias: '→ llama-3.1-8b-instant' },
336
+ { id: 'rp:cheap', provider: 'groq', alias: '→ llama-3.1-8b-instant' },
337
+ { id: 'rp:best', provider: 'anthropic', alias: '→ claude-3-5-sonnet-20241022' },
338
+ { id: 'rp:balanced', provider: 'openai', alias: '→ gpt-4o-mini' },
339
+ ];
340
+ sendJson(res, 200, {
341
+ object: 'list',
342
+ data: models.map(m => ({
343
+ id: m.id,
344
+ object: 'model',
345
+ owned_by: m.provider,
346
+ relayplane_alias: m.alias,
347
+ })),
348
+ });
349
+ }
350
+ /**
351
+ * Handle chat completions (and other API endpoints)
352
+ */
353
+ async function handleProxy(req, res, pathname) {
354
+ const startMs = Date.now();
355
+ const isDryRun = req.headers['x-dry-run'] === 'true';
356
+ try {
357
+ const body = await parseBody(req);
358
+ let data;
359
+ try {
360
+ data = JSON.parse(body);
361
+ }
362
+ catch {
363
+ sendJson(res, 400, { error: { message: 'Invalid JSON body' } });
364
+ return;
365
+ }
366
+ let model = data.model || 'gpt-4o';
367
+ let provider;
368
+ // Resolve model alias
369
+ if (MODEL_ALIASES[model]) {
370
+ const alias = MODEL_ALIASES[model];
371
+ model = alias.model;
372
+ provider = alias.provider;
373
+ data.model = model;
374
+ }
375
+ else {
376
+ provider = detectProvider(model);
377
+ }
378
+ const providerConfig = PROVIDERS[provider];
379
+ if (!providerConfig) {
380
+ sendJson(res, 400, { error: { message: `Unknown provider for model: ${model}` } });
381
+ return;
382
+ }
383
+ const apiKey = process.env[providerConfig.apiKeyEnv];
384
+ if (!apiKey) {
385
+ sendJson(res, 401, {
386
+ error: { message: `Missing API key: ${providerConfig.apiKeyEnv}` },
387
+ });
388
+ return;
389
+ }
390
+ // Estimate tokens (rough estimate)
391
+ const inputTokens = Math.ceil(JSON.stringify(data.messages || data).length / 4);
392
+ const expectedOutputTokens = data.max_tokens || 500;
393
+ const estimatedCost = estimateCost(model, inputTokens, expectedOutputTokens);
394
+ // Check spending limits
395
+ const config = loadConfig();
396
+ const dailyUsage = loadDailyUsage();
397
+ const monthlyUsage = loadMonthlyUsage();
398
+ if (config?.limits?.daily) {
399
+ if (dailyUsage.cost + estimatedCost > config.limits.daily) {
400
+ sendJson(res, 429, {
401
+ error: {
402
+ message: `Daily spending limit reached ($${dailyUsage.cost.toFixed(2)} / $${config.limits.daily})`,
403
+ code: 'spending_limit_exceeded',
404
+ },
405
+ });
406
+ return;
407
+ }
408
+ }
409
+ if (config?.limits?.monthly) {
410
+ if (monthlyUsage.cost + estimatedCost > config.limits.monthly) {
411
+ sendJson(res, 429, {
412
+ error: {
413
+ message: `Monthly spending limit reached ($${monthlyUsage.cost.toFixed(2)} / $${config.limits.monthly})`,
414
+ code: 'spending_limit_exceeded',
415
+ },
416
+ });
417
+ return;
418
+ }
419
+ }
420
+ // Dry run mode - return estimate without making actual request
421
+ if (isDryRun) {
422
+ sendJson(res, 200, {
423
+ dry_run: true,
424
+ routing: {
425
+ model,
426
+ provider,
427
+ endpoint: `${providerConfig.baseUrl}${pathname}`,
428
+ },
429
+ estimate: {
430
+ inputTokens,
431
+ expectedOutputTokens,
432
+ estimatedCost,
433
+ currency: 'USD',
434
+ },
435
+ limits: {
436
+ daily: config?.limits?.daily,
437
+ dailyUsed: dailyUsage.cost,
438
+ dailyRemaining: config?.limits?.daily
439
+ ? config.limits.daily - dailyUsage.cost
440
+ : null,
441
+ monthly: config?.limits?.monthly,
442
+ monthlyUsed: monthlyUsage.cost,
443
+ monthlyRemaining: config?.limits?.monthly
444
+ ? config.limits.monthly - monthlyUsage.cost
445
+ : null,
446
+ },
447
+ });
448
+ return;
449
+ }
450
+ // Make actual request to provider
451
+ const url = new URL(pathname, providerConfig.baseUrl);
452
+ const headers = {
453
+ 'Content-Type': 'application/json',
454
+ 'User-Agent': `relayplane-proxy/${VERSION}`,
455
+ [providerConfig.headerName]: providerConfig.headerPrefix + apiKey,
456
+ ...providerConfig.extraHeaders,
457
+ };
458
+ const proxyReq = (url.protocol === 'https:' ? https : http).request(url, {
459
+ method: 'POST',
460
+ headers,
461
+ }, proxyRes => {
462
+ const chunks = [];
463
+ proxyRes.on('data', chunk => chunks.push(chunk));
464
+ proxyRes.on('end', () => {
465
+ const responseBody = Buffer.concat(chunks).toString();
466
+ const latencyMs = Date.now() - startMs;
467
+ // Parse response for usage tracking
468
+ let outputTokens = expectedOutputTokens;
469
+ let success = proxyRes.statusCode === 200;
470
+ try {
471
+ const respData = JSON.parse(responseBody);
472
+ if (respData.usage) {
473
+ outputTokens = respData.usage.completion_tokens || outputTokens;
474
+ }
475
+ }
476
+ catch {
477
+ // Ignore parse errors
478
+ }
479
+ const actualCost = estimateCost(model, inputTokens, outputTokens);
480
+ // Update stats
481
+ stats.requestsHandled++;
482
+ if (success) {
483
+ stats.requestsSuccessful++;
484
+ }
485
+ else {
486
+ stats.requestsFailed++;
487
+ }
488
+ stats.totalInputTokens += inputTokens;
489
+ stats.totalOutputTokens += outputTokens;
490
+ stats.totalCost += actualCost;
491
+ // Update model stats
492
+ const modelStats = stats.byModel.get(model) || { requests: 0, tokens: 0, cost: 0 };
493
+ modelStats.requests++;
494
+ modelStats.tokens += inputTokens + outputTokens;
495
+ modelStats.cost += actualCost;
496
+ stats.byModel.set(model, modelStats);
497
+ // Update provider stats
498
+ const providerStats = stats.byProvider.get(provider) || { requests: 0, tokens: 0, cost: 0 };
499
+ providerStats.requests++;
500
+ providerStats.tokens += inputTokens + outputTokens;
501
+ providerStats.cost += actualCost;
502
+ stats.byProvider.set(provider, providerStats);
503
+ // Update daily usage
504
+ dailyUsage.cost += actualCost;
505
+ dailyUsage.requests++;
506
+ saveDailyUsage(dailyUsage);
507
+ // Update monthly usage
508
+ monthlyUsage.cost += actualCost;
509
+ monthlyUsage.requests++;
510
+ saveMonthlyUsage(monthlyUsage);
511
+ // Log usage
512
+ logUsage({
513
+ timestamp: new Date().toISOString(),
514
+ model,
515
+ provider,
516
+ inputTokens,
517
+ outputTokens,
518
+ cost: actualCost,
519
+ latencyMs,
520
+ success,
521
+ });
522
+ // Check limits and log warnings to console
523
+ const usageWarning = checkAndWarnLimits(dailyUsage, monthlyUsage, config);
524
+ // Add usage warning header if approaching limit
525
+ const responseHeaders = {
526
+ 'Content-Type': 'application/json',
527
+ 'Access-Control-Allow-Origin': '*',
528
+ 'X-RelayPlane-Cost': actualCost.toFixed(6),
529
+ 'X-RelayPlane-Latency': latencyMs.toString(),
530
+ };
531
+ if (config?.limits?.daily) {
532
+ responseHeaders['X-RelayPlane-Daily-Usage'] = `${dailyUsage.cost.toFixed(2)}/${config.limits.daily}`;
533
+ }
534
+ if (config?.limits?.monthly) {
535
+ responseHeaders['X-RelayPlane-Monthly-Usage'] = `${monthlyUsage.cost.toFixed(2)}/${config.limits.monthly}`;
536
+ }
537
+ if (usageWarning) {
538
+ responseHeaders['X-RelayPlane-Usage-Warning'] = usageWarning;
539
+ }
540
+ res.writeHead(proxyRes.statusCode || 200, responseHeaders);
541
+ res.end(responseBody);
542
+ });
543
+ });
544
+ proxyReq.on('error', error => {
545
+ stats.requestsHandled++;
546
+ stats.requestsFailed++;
547
+ logUsage({
548
+ timestamp: new Date().toISOString(),
549
+ model,
550
+ provider,
551
+ inputTokens,
552
+ outputTokens: 0,
553
+ cost: 0,
554
+ latencyMs: Date.now() - startMs,
555
+ success: false,
556
+ });
557
+ sendJson(res, 502, { error: { message: `Proxy error: ${error.message}` } });
558
+ });
559
+ proxyReq.write(JSON.stringify(data));
560
+ proxyReq.end();
561
+ }
562
+ catch (error) {
563
+ sendJson(res, 500, { error: { message: error.message } });
564
+ }
565
+ }
566
+ /**
567
+ * Main request handler
568
+ */
569
+ function handleRequest(req, res) {
570
+ const url = new URL(req.url || '/', `http://${HOST}:${PORT}`);
571
+ const pathname = url.pathname;
572
+ // CORS preflight
573
+ if (req.method === 'OPTIONS') {
574
+ res.writeHead(204, {
575
+ 'Access-Control-Allow-Origin': '*',
576
+ 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
577
+ 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Dry-Run',
578
+ });
579
+ res.end();
580
+ return;
581
+ }
582
+ // Health check endpoint
583
+ if (pathname === '/health' && req.method === 'GET') {
584
+ handleHealth(res);
585
+ return;
586
+ }
587
+ // Models endpoint
588
+ if (pathname === '/v1/models' && req.method === 'GET') {
589
+ handleModels(res);
590
+ return;
591
+ }
592
+ // Chat completions and other API endpoints
593
+ if (pathname.startsWith('/v1/') && req.method === 'POST') {
594
+ handleProxy(req, res, pathname);
595
+ return;
596
+ }
597
+ // Root endpoint
598
+ if (pathname === '/' && req.method === 'GET') {
599
+ sendJson(res, 200, {
600
+ name: 'RelayPlane Proxy',
601
+ version: VERSION,
602
+ status: 'ok',
603
+ endpoints: {
604
+ health: '/health',
605
+ models: '/v1/models',
606
+ chat: '/v1/chat/completions',
607
+ },
608
+ });
609
+ return;
610
+ }
611
+ // 404 for unknown routes
612
+ sendJson(res, 404, { error: { message: 'Not found' } });
613
+ }
614
+ // Create and start server
615
+ const server = http.createServer(handleRequest);
616
+ server.listen(PORT, HOST, () => {
617
+ console.log(`🚀 RelayPlane Proxy v${VERSION}`);
618
+ console.log(` Listening on http://${HOST}:${PORT}`);
619
+ console.log(` Health check: http://${HOST}:${PORT}/health`);
620
+ console.log(` Press Ctrl+C to stop`);
621
+ });
622
+ // Graceful shutdown
623
+ process.on('SIGTERM', () => {
624
+ console.log('\nShutting down...');
625
+ server.close(() => {
626
+ console.log('Server stopped.');
627
+ process.exit(0);
628
+ });
629
+ });
630
+ process.on('SIGINT', () => {
631
+ console.log('\nShutting down...');
632
+ server.close(() => {
633
+ console.log('Server stopped.');
634
+ process.exit(0);
635
+ });
636
+ });
637
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}