vertex-ai-proxy 1.0.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/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const server_js_1 = require("./server.js");
5
+ const args = process.argv.slice(2);
6
+ const config = {};
7
+ for (let i = 0; i < args.length; i++) {
8
+ const arg = args[i];
9
+ const next = args[i + 1];
10
+ switch (arg) {
11
+ case '--port':
12
+ case '-p':
13
+ config.port = parseInt(next);
14
+ i++;
15
+ break;
16
+ case '--host':
17
+ config.host = next;
18
+ i++;
19
+ break;
20
+ case '--project':
21
+ config.projectId = next;
22
+ i++;
23
+ break;
24
+ case '--claude-regions':
25
+ config.claudeRegions = next.split(',');
26
+ i++;
27
+ break;
28
+ case '--gemini-location':
29
+ config.geminiLocation = next;
30
+ i++;
31
+ break;
32
+ case '--max-concurrent':
33
+ config.maxConcurrent = parseInt(next);
34
+ i++;
35
+ break;
36
+ case '--enable-logging':
37
+ config.enableRequestLogging = true;
38
+ break;
39
+ case '--disable-cache':
40
+ config.enablePromptCache = false;
41
+ break;
42
+ case '--disable-metrics':
43
+ config.enableMetrics = false;
44
+ break;
45
+ case '-h':
46
+ case '--help':
47
+ console.log('Vertex AI Proxy - OpenAI-compatible API for Claude/Gemini on Vertex AI\n');
48
+ console.log('Usage: vertex-proxy [options]\n');
49
+ console.log('Options:');
50
+ console.log(' -p, --port <port> Server port (default: 8001)');
51
+ console.log(' --project <id> Google Cloud project ID');
52
+ console.log(' --claude-regions <list> Comma-separated regions');
53
+ console.log(' --max-concurrent <n> Max concurrent requests');
54
+ console.log(' --enable-logging Enable request logging');
55
+ console.log(' --disable-cache Disable prompt caching');
56
+ console.log(' -h, --help Show help');
57
+ process.exit(0);
58
+ }
59
+ }
60
+ const projectId = config.projectId || process.env.PROJECT_ID || process.env.GOOGLE_CLOUD_PROJECT;
61
+ if (!projectId) {
62
+ console.error('Error: PROJECT_ID required');
63
+ process.exit(1);
64
+ }
65
+ config.projectId = projectId;
66
+ (0, server_js_1.startServer)(config);
67
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AACA,2CAA0C;AAG1C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,MAAM,GAAwB,EAAE,CAAC;AAEvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAEzB,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,QAAQ,CAAC;QAAC,KAAK,IAAI;YAAE,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAAC,CAAC,EAAE,CAAC;YAAC,MAAM;QACnE,KAAK,QAAQ;YAAE,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;YAAC,CAAC,EAAE,CAAC;YAAC,MAAM;QAC9C,KAAK,WAAW;YAAE,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC;YAAC,CAAC,EAAE,CAAC;YAAC,MAAM;QACtD,KAAK,kBAAkB;YAAE,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAAC,CAAC,EAAE,CAAC;YAAC,MAAM;QAC5E,KAAK,mBAAmB;YAAE,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC;YAAC,CAAC,EAAE,CAAC;YAAC,MAAM;QACnE,KAAK,kBAAkB;YAAE,MAAM,CAAC,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAAC,CAAC,EAAE,CAAC;YAAC,MAAM;QAC3E,KAAK,kBAAkB;YAAE,MAAM,CAAC,oBAAoB,GAAG,IAAI,CAAC;YAAC,MAAM;QACnE,KAAK,iBAAiB;YAAE,MAAM,CAAC,iBAAiB,GAAG,KAAK,CAAC;YAAC,MAAM;QAChE,KAAK,mBAAmB;YAAE,MAAM,CAAC,aAAa,GAAG,KAAK,CAAC;YAAC,MAAM;QAC9D,KAAK,IAAI,CAAC;QAAC,KAAK,QAAQ;YACtB,OAAO,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC;YACxF,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;YACtE,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;YAClE,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;YAClE,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;YAClE,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;YACjE,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;YACjE,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;AACjG,IAAI,CAAC,SAAS,EAAE,CAAC;IACf,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;AAC7B,IAAA,uBAAW,EAAC,MAAM,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { createServer, startServer } from './server.js';
2
+ export { ProxyConfig, DEFAULT_CONFIG, CLAUDE_MODELS, GEMINI_MODELS } from './types.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GEMINI_MODELS = exports.CLAUDE_MODELS = exports.DEFAULT_CONFIG = exports.startServer = exports.createServer = void 0;
4
+ var server_js_1 = require("./server.js");
5
+ Object.defineProperty(exports, "createServer", { enumerable: true, get: function () { return server_js_1.createServer; } });
6
+ Object.defineProperty(exports, "startServer", { enumerable: true, get: function () { return server_js_1.startServer; } });
7
+ var types_js_1 = require("./types.js");
8
+ Object.defineProperty(exports, "DEFAULT_CONFIG", { enumerable: true, get: function () { return types_js_1.DEFAULT_CONFIG; } });
9
+ Object.defineProperty(exports, "CLAUDE_MODELS", { enumerable: true, get: function () { return types_js_1.CLAUDE_MODELS; } });
10
+ Object.defineProperty(exports, "GEMINI_MODELS", { enumerable: true, get: function () { return types_js_1.GEMINI_MODELS; } });
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAAwD;AAA/C,yGAAA,YAAY,OAAA;AAAE,wGAAA,WAAW,OAAA;AAClC,uCAAuF;AAAjE,0GAAA,cAAc,OAAA;AAAE,yGAAA,aAAa,OAAA;AAAE,yGAAA,aAAa,OAAA"}
@@ -0,0 +1,22 @@
1
+ import { ProxyConfig } from './types.js';
2
+ export declare function createServer(config?: Partial<ProxyConfig>): {
3
+ app: import("express-serve-static-core").Express;
4
+ config: {
5
+ projectId: string;
6
+ claudeRegions: string[];
7
+ geminiLocation: string;
8
+ port: number;
9
+ host: string;
10
+ maxRetries: number;
11
+ retryBaseDelay: number;
12
+ requestTimeout: number;
13
+ enablePromptCache: boolean;
14
+ enableMetrics: boolean;
15
+ enableRequestLogging: boolean;
16
+ heartbeatInterval: number;
17
+ maxConcurrent: number;
18
+ queueSize: number;
19
+ };
20
+ };
21
+ export declare function startServer(config?: Partial<ProxyConfig>): void;
22
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,WAAW,EAEZ,MAAM,YAAY,CAAC;AAwNpB,wBAAgB,YAAY,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM;;;;;;;;;;;;;;;;;;EAuI7D;AAED,wBAAgB,WAAW,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,IAAI,CAOnE"}
package/dist/server.js ADDED
@@ -0,0 +1,390 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createServer = createServer;
7
+ exports.startServer = startServer;
8
+ const express_1 = __importDefault(require("express"));
9
+ const vertex_sdk_1 = require("@anthropic-ai/vertex-sdk");
10
+ const genai_1 = require("@google/genai");
11
+ const types_js_1 = require("./types.js");
12
+ // Request Queue for concurrency control
13
+ class RequestQueue {
14
+ maxConcurrent;
15
+ maxQueueSize;
16
+ queue = [];
17
+ activeCount = 0;
18
+ constructor(maxConcurrent, maxQueueSize) {
19
+ this.maxConcurrent = maxConcurrent;
20
+ this.maxQueueSize = maxQueueSize;
21
+ }
22
+ async acquire() {
23
+ if (this.activeCount < this.maxConcurrent) {
24
+ this.activeCount++;
25
+ return;
26
+ }
27
+ if (this.queue.length >= this.maxQueueSize) {
28
+ throw new Error('Queue full');
29
+ }
30
+ return new Promise((resolve, reject) => {
31
+ this.queue.push({ resolve, reject });
32
+ });
33
+ }
34
+ release() {
35
+ this.activeCount--;
36
+ const next = this.queue.shift();
37
+ if (next) {
38
+ this.activeCount++;
39
+ next.resolve();
40
+ }
41
+ }
42
+ get stats() {
43
+ return { active: this.activeCount, queued: this.queue.length };
44
+ }
45
+ }
46
+ // Metrics collector
47
+ class Metrics {
48
+ enabled;
49
+ requestsTotal = new Map();
50
+ requestDurations = [];
51
+ retriesTotal = new Map();
52
+ regionFailures = new Map();
53
+ cacheHits = 0;
54
+ constructor(enabled) {
55
+ this.enabled = enabled;
56
+ }
57
+ incRequest(model, status) {
58
+ if (!this.enabled)
59
+ return;
60
+ const key = `${model}:${status}`;
61
+ this.requestsTotal.set(key, (this.requestsTotal.get(key) || 0) + 1);
62
+ }
63
+ observeDuration(duration) {
64
+ if (!this.enabled)
65
+ return;
66
+ this.requestDurations.push(duration);
67
+ if (this.requestDurations.length > 1000)
68
+ this.requestDurations.shift();
69
+ }
70
+ incRetry(model, region) {
71
+ if (!this.enabled)
72
+ return;
73
+ const key = `${model}:${region}`;
74
+ this.retriesTotal.set(key, (this.retriesTotal.get(key) || 0) + 1);
75
+ }
76
+ incRegionFailure(region) {
77
+ if (!this.enabled)
78
+ return;
79
+ this.regionFailures.set(region, (this.regionFailures.get(region) || 0) + 1);
80
+ }
81
+ incCacheHit() {
82
+ if (this.enabled)
83
+ this.cacheHits++;
84
+ }
85
+ getPrometheusMetrics() {
86
+ const lines = [];
87
+ lines.push('# HELP vertex_proxy_requests_total Total requests');
88
+ lines.push('# TYPE vertex_proxy_requests_total counter');
89
+ for (const [key, value] of this.requestsTotal) {
90
+ const [model, stat] = key.split(':');
91
+ lines.push(`vertex_proxy_requests_total{model="${model}",status="${stat}"} ${value}`);
92
+ }
93
+ lines.push(`# HELP vertex_proxy_cache_hits_total Cache hits`);
94
+ lines.push(`# TYPE vertex_proxy_cache_hits_total counter`);
95
+ lines.push(`vertex_proxy_cache_hits_total ${this.cacheHits}`);
96
+ return lines.join('\n');
97
+ }
98
+ }
99
+ // Client pool with region failover
100
+ class ClientPool {
101
+ config;
102
+ metrics;
103
+ claudeClients = new Map();
104
+ geminiClient = null;
105
+ regionHealth = new Map();
106
+ constructor(config, metrics) {
107
+ this.config = config;
108
+ this.metrics = metrics;
109
+ this.initClients();
110
+ }
111
+ initClients() {
112
+ for (const region of this.config.claudeRegions) {
113
+ try {
114
+ this.claudeClients.set(region.trim(), new vertex_sdk_1.AnthropicVertex({
115
+ projectId: this.config.projectId,
116
+ region: region.trim(),
117
+ }));
118
+ this.regionHealth.set(region.trim(), Date.now());
119
+ console.log(`Initialized Claude client for region: ${region}`);
120
+ }
121
+ catch (e) {
122
+ console.warn(`Failed to init Claude client for ${region}: ${e}`);
123
+ }
124
+ }
125
+ try {
126
+ this.geminiClient = new genai_1.GoogleGenAI({
127
+ vertexai: true,
128
+ project: this.config.projectId,
129
+ location: this.config.geminiLocation,
130
+ });
131
+ console.log(`Initialized Gemini client for: ${this.config.geminiLocation}`);
132
+ }
133
+ catch (e) {
134
+ console.warn(`Failed to init Gemini client: ${e}`);
135
+ }
136
+ }
137
+ getClaudeClient() {
138
+ const sorted = [...this.regionHealth.entries()].sort((a, b) => b[1] - a[1]);
139
+ for (const [region] of sorted) {
140
+ const client = this.claudeClients.get(region);
141
+ if (client)
142
+ return { client, region };
143
+ }
144
+ throw new Error('No Claude clients available');
145
+ }
146
+ getGeminiClient() {
147
+ if (!this.geminiClient)
148
+ throw new Error('Gemini client not available');
149
+ return this.geminiClient;
150
+ }
151
+ markRegionSuccess(region) { this.regionHealth.set(region, Date.now()); }
152
+ markRegionFailure(region) { this.regionHealth.set(region, 0); this.metrics.incRegionFailure(region); }
153
+ }
154
+ // Helpers
155
+ function getModelType(model) {
156
+ if (!model)
157
+ return { type: 'claude', modelId: types_js_1.CLAUDE_MODELS['opus'] };
158
+ const ml = model.toLowerCase();
159
+ if (ml in types_js_1.CLAUDE_MODELS)
160
+ return { type: 'claude', modelId: types_js_1.CLAUDE_MODELS[ml] };
161
+ if (ml in types_js_1.GEMINI_MODELS)
162
+ return { type: 'gemini', modelId: types_js_1.GEMINI_MODELS[ml] };
163
+ if (ml.includes('gemini'))
164
+ return { type: 'gemini', modelId: model };
165
+ return { type: 'claude', modelId: types_js_1.CLAUDE_MODELS[ml] || types_js_1.CLAUDE_MODELS['opus'] };
166
+ }
167
+ function processContent(content) {
168
+ if (typeof content === 'string')
169
+ return content;
170
+ if (!Array.isArray(content))
171
+ return String(content || '');
172
+ return content.map(item => {
173
+ if (item?.type === 'text')
174
+ return { type: 'text', text: item.text || '' };
175
+ if (item?.type === 'image_url') {
176
+ const url = item.image_url?.url || '';
177
+ if (url.startsWith('data:')) {
178
+ const [meta, data] = url.split(',');
179
+ const mediaType = meta.includes(':') ? meta.split(':')[1].split(';')[0] : 'image/png';
180
+ return { type: 'image', source: { type: 'base64', media_type: mediaType, data } };
181
+ }
182
+ }
183
+ return item;
184
+ }).filter(Boolean);
185
+ }
186
+ function convertTools(tools) {
187
+ if (!tools?.length)
188
+ return undefined;
189
+ return tools.filter(t => t.type === 'function').map(t => ({
190
+ name: t.function.name,
191
+ description: t.function.description || '',
192
+ input_schema: t.function.parameters || {},
193
+ }));
194
+ }
195
+ function extractSystemAndMessages(messages, enableCache) {
196
+ const systemParts = [];
197
+ const anthropicMsgs = [];
198
+ for (const msg of messages) {
199
+ if (msg.role === 'system') {
200
+ systemParts.push(typeof msg.content === 'string' ? msg.content : '');
201
+ }
202
+ else if (msg.role === 'tool') {
203
+ anthropicMsgs.push({
204
+ role: 'user',
205
+ content: [{ type: 'tool_result', tool_use_id: msg.tool_call_id || '', content: typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content) }],
206
+ });
207
+ }
208
+ else if (msg.role === 'user' || msg.role === 'assistant') {
209
+ let processed = processContent(msg.content);
210
+ if (msg.role === 'assistant' && msg.tool_calls?.length) {
211
+ processed = msg.tool_calls.map(tc => ({
212
+ type: 'tool_use', id: tc.id, name: tc.function.name,
213
+ input: JSON.parse(tc.function.arguments || '{}'),
214
+ }));
215
+ }
216
+ anthropicMsgs.push({ role: msg.role, content: processed });
217
+ }
218
+ }
219
+ let system = systemParts.length ? systemParts.join('\n\n') : undefined;
220
+ if (enableCache && system && typeof system === 'string' && system.length > 1024) {
221
+ system = [{ type: 'text', text: system, cache_control: { type: 'ephemeral' } }];
222
+ }
223
+ return { system, messages: anthropicMsgs };
224
+ }
225
+ function makeStreamChunk(id, model, delta, finishReason) {
226
+ return { id, object: 'chat.completion.chunk', created: Math.floor(Date.now() / 1000), model, choices: [{ index: 0, delta, finish_reason: finishReason }] };
227
+ }
228
+ const sleep = (ms) => new Promise(r => setTimeout(r, ms));
229
+ // Main server
230
+ function createServer(config = {}) {
231
+ const finalConfig = { ...types_js_1.DEFAULT_CONFIG, ...config };
232
+ const metrics = new Metrics(finalConfig.enableMetrics);
233
+ const pool = new ClientPool(finalConfig, metrics);
234
+ const queue = new RequestQueue(finalConfig.maxConcurrent, finalConfig.queueSize);
235
+ const app = (0, express_1.default)();
236
+ app.use(express_1.default.json({ limit: '50mb' }));
237
+ app.use((req, res, next) => {
238
+ res.header('Access-Control-Allow-Origin', '*');
239
+ res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
240
+ res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
241
+ if (req.method === 'OPTIONS')
242
+ return res.sendStatus(200);
243
+ next();
244
+ });
245
+ app.get(['/', '/health'], (req, res) => {
246
+ res.json({ status: 'ok', version: '1.0.0', project: finalConfig.projectId, claude_regions: finalConfig.claudeRegions, gemini_location: finalConfig.geminiLocation, queue: queue.stats });
247
+ });
248
+ app.get('/metrics', (req, res) => {
249
+ if (!finalConfig.enableMetrics)
250
+ return res.status(404).send('Metrics disabled');
251
+ res.type('text/plain').send(metrics.getPrometheusMetrics());
252
+ });
253
+ app.post('/v1/chat/completions', async (req, res) => {
254
+ const startTime = Date.now();
255
+ try {
256
+ await queue.acquire();
257
+ }
258
+ catch {
259
+ return res.status(429).json({ error: { message: 'Too many requests' } });
260
+ }
261
+ const timeoutId = setTimeout(() => { if (!res.headersSent)
262
+ res.status(504).json({ error: { message: 'Timeout' } }); }, finalConfig.requestTimeout * 1000);
263
+ try {
264
+ const body = req.body;
265
+ const { type: modelType, modelId } = getModelType(body.model);
266
+ const chunkId = `chatcmpl-${Date.now()}`;
267
+ if (finalConfig.enableRequestLogging)
268
+ console.log(`[${modelType.toUpperCase()}] model=${modelId}, msgs=${body.messages?.length}, stream=${body.stream}`);
269
+ if (modelType === 'gemini') {
270
+ const prompt = body.messages.map(m => `${m.role}: ${m.content}`).join('\n');
271
+ const client = pool.getGeminiClient();
272
+ if (body.stream) {
273
+ res.setHeader('Content-Type', 'text/event-stream');
274
+ res.write(`data: ${JSON.stringify(makeStreamChunk(chunkId, modelId, { role: 'assistant' }, null))}\n\n`);
275
+ const stream = await client.models.generateContentStream({ model: modelId, contents: prompt });
276
+ for await (const chunk of stream) {
277
+ if (chunk.text)
278
+ res.write(`data: ${JSON.stringify(makeStreamChunk(chunkId, modelId, { content: chunk.text }, null))}\n\n`);
279
+ }
280
+ res.write(`data: ${JSON.stringify(makeStreamChunk(chunkId, modelId, {}, 'stop'))}\n\n`);
281
+ res.write('data: [DONE]\n\n');
282
+ return res.end();
283
+ }
284
+ const resp = await client.models.generateContent({ model: modelId, contents: prompt });
285
+ return res.json({ id: chunkId, object: 'chat.completion', created: Math.floor(Date.now() / 1000), model: modelId, choices: [{ index: 0, message: { role: 'assistant', content: resp.text }, finish_reason: 'stop' }], usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 } });
286
+ }
287
+ // Claude
288
+ const { system, messages: anthropicMsgs } = extractSystemAndMessages(body.messages, finalConfig.enablePromptCache);
289
+ const claudeParams = { model: modelId, max_tokens: body.max_tokens || 8192, messages: anthropicMsgs };
290
+ if (system)
291
+ claudeParams.system = system;
292
+ if (body.temperature !== undefined)
293
+ claudeParams.temperature = body.temperature;
294
+ if (body.tools)
295
+ claudeParams.tools = convertTools(body.tools);
296
+ let lastError = null;
297
+ for (let attempt = 0; attempt < finalConfig.maxRetries; attempt++) {
298
+ const { client, region } = pool.getClaudeClient();
299
+ try {
300
+ if (body.stream && !body.tools) {
301
+ res.setHeader('Content-Type', 'text/event-stream');
302
+ res.write(`data: ${JSON.stringify(makeStreamChunk(chunkId, modelId, { role: 'assistant' }, null))}\n\n`);
303
+ let lastHb = Date.now();
304
+ const stream = client.messages.stream(claudeParams);
305
+ for await (const event of stream) {
306
+ if (event.type === 'content_block_delta' && event.delta.type === 'text_delta') {
307
+ res.write(`data: ${JSON.stringify(makeStreamChunk(chunkId, modelId, { content: event.delta.text }, null))}\n\n`);
308
+ }
309
+ if (Date.now() - lastHb > finalConfig.heartbeatInterval * 1000) {
310
+ res.write(': ping\n\n');
311
+ lastHb = Date.now();
312
+ }
313
+ }
314
+ res.write(`data: ${JSON.stringify(makeStreamChunk(chunkId, modelId, {}, 'stop'))}\n\n`);
315
+ res.write('data: [DONE]\n\n');
316
+ pool.markRegionSuccess(region);
317
+ metrics.incRequest(modelId, 'success');
318
+ return res.end();
319
+ }
320
+ const response = await client.messages.create(claudeParams);
321
+ pool.markRegionSuccess(region);
322
+ let contentText = '';
323
+ const toolCalls = [];
324
+ for (const block of response.content) {
325
+ if ('text' in block)
326
+ contentText += block.text;
327
+ if (block.type === 'tool_use')
328
+ toolCalls.push({ id: block.id, type: 'function', function: { name: block.name, arguments: JSON.stringify(block.input) } });
329
+ }
330
+ const msg = { role: 'assistant', content: contentText || null };
331
+ if (toolCalls.length)
332
+ msg.tool_calls = toolCalls;
333
+ const result = { id: `chatcmpl-${response.id}`, object: 'chat.completion', created: Math.floor(Date.now() / 1000), model: modelId, choices: [{ index: 0, message: msg, finish_reason: toolCalls.length ? 'tool_calls' : 'stop' }], usage: { prompt_tokens: response.usage.input_tokens, completion_tokens: response.usage.output_tokens, total_tokens: response.usage.input_tokens + response.usage.output_tokens } };
334
+ metrics.incRequest(modelId, 'success');
335
+ metrics.observeDuration((Date.now() - startTime) / 1000);
336
+ if (body.stream) {
337
+ res.setHeader('Content-Type', 'text/event-stream');
338
+ res.write(`data: ${JSON.stringify(makeStreamChunk(chunkId, modelId, { role: 'assistant' }, null))}\n\n`);
339
+ if (contentText)
340
+ res.write(`data: ${JSON.stringify(makeStreamChunk(chunkId, modelId, { content: contentText }, null))}\n\n`);
341
+ for (let i = 0; i < toolCalls.length; i++) {
342
+ const tc = toolCalls[i];
343
+ res.write(`data: ${JSON.stringify(makeStreamChunk(chunkId, modelId, { tool_calls: [{ index: i, id: tc.id, type: 'function', function: { name: tc.function.name, arguments: '' } }] }, null))}\n\n`);
344
+ res.write(`data: ${JSON.stringify(makeStreamChunk(chunkId, modelId, { tool_calls: [{ index: i, function: { arguments: tc.function.arguments } }] }, null))}\n\n`);
345
+ }
346
+ res.write(`data: ${JSON.stringify(makeStreamChunk(chunkId, modelId, {}, toolCalls.length ? 'tool_calls' : 'stop'))}\n\n`);
347
+ res.write('data: [DONE]\n\n');
348
+ return res.end();
349
+ }
350
+ return res.json(result);
351
+ }
352
+ catch (e) {
353
+ lastError = e;
354
+ if (e?.status === 429) {
355
+ pool.markRegionFailure(region);
356
+ metrics.incRetry(modelId, region);
357
+ continue;
358
+ }
359
+ if (e?.status >= 500) {
360
+ metrics.incRetry(modelId, region);
361
+ await sleep(finalConfig.retryBaseDelay * Math.pow(2, attempt) * 1000);
362
+ continue;
363
+ }
364
+ throw e;
365
+ }
366
+ }
367
+ throw lastError || new Error('All retries exhausted');
368
+ }
369
+ catch (e) {
370
+ console.error('Error:', e.message || e);
371
+ metrics.incRequest(req.body?.model || 'unknown', 'error');
372
+ if (!res.headersSent)
373
+ res.status(500).json({ error: { message: e.message || 'Internal error' } });
374
+ }
375
+ finally {
376
+ clearTimeout(timeoutId);
377
+ queue.release();
378
+ }
379
+ });
380
+ return { app, config: finalConfig };
381
+ }
382
+ function startServer(config = {}) {
383
+ const { app, config: finalConfig } = createServer(config);
384
+ app.listen(finalConfig.port, finalConfig.host, () => {
385
+ console.log(`Vertex AI Proxy running at http://${finalConfig.host}:${finalConfig.port}`);
386
+ console.log(`Project: ${finalConfig.projectId}`);
387
+ console.log(`Claude regions: ${finalConfig.claudeRegions.join(', ')}`);
388
+ });
389
+ }
390
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ export interface ProxyConfig {
2
+ projectId: string;
3
+ claudeRegions: string[];
4
+ geminiLocation: string;
5
+ port: number;
6
+ host: string;
7
+ maxRetries: number;
8
+ retryBaseDelay: number;
9
+ requestTimeout: number;
10
+ enablePromptCache: boolean;
11
+ enableMetrics: boolean;
12
+ enableRequestLogging: boolean;
13
+ heartbeatInterval: number;
14
+ maxConcurrent: number;
15
+ queueSize: number;
16
+ }
17
+ export interface Message {
18
+ role: 'system' | 'user' | 'assistant' | 'tool';
19
+ content: string | ContentBlock[];
20
+ tool_calls?: ToolCall[];
21
+ tool_call_id?: string;
22
+ }
23
+ export interface ContentBlock {
24
+ type: 'text' | 'image_url' | 'image';
25
+ text?: string;
26
+ image_url?: {
27
+ url: string;
28
+ };
29
+ source?: {
30
+ type: string;
31
+ media_type: string;
32
+ data: string;
33
+ };
34
+ }
35
+ export interface ToolCall {
36
+ id: string;
37
+ type: 'function';
38
+ function: {
39
+ name: string;
40
+ arguments: string;
41
+ };
42
+ }
43
+ export interface Tool {
44
+ type: 'function';
45
+ function: {
46
+ name: string;
47
+ description?: string;
48
+ parameters?: Record<string, unknown>;
49
+ };
50
+ }
51
+ export interface ChatRequest {
52
+ model?: string;
53
+ messages: Message[];
54
+ stream?: boolean;
55
+ tools?: Tool[];
56
+ max_tokens?: number;
57
+ temperature?: number;
58
+ }
59
+ export interface StreamChunk {
60
+ id: string;
61
+ object: 'chat.completion.chunk';
62
+ created: number;
63
+ model: string;
64
+ choices: Array<{
65
+ index: number;
66
+ delta: {
67
+ role?: string;
68
+ content?: string;
69
+ tool_calls?: Array<{
70
+ index: number;
71
+ id?: string;
72
+ type?: string;
73
+ function?: {
74
+ name?: string;
75
+ arguments?: string;
76
+ };
77
+ }>;
78
+ };
79
+ finish_reason: string | null;
80
+ }>;
81
+ }
82
+ export declare const DEFAULT_CONFIG: ProxyConfig;
83
+ export declare const CLAUDE_MODELS: Record<string, string>;
84
+ export declare const GEMINI_MODELS: Record<string, string>;
85
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GEMINI_MODELS = exports.CLAUDE_MODELS = exports.DEFAULT_CONFIG = void 0;
4
+ exports.DEFAULT_CONFIG = {
5
+ projectId: process.env.PROJECT_ID || process.env.GOOGLE_CLOUD_PROJECT || '',
6
+ claudeRegions: (process.env.CLAUDE_REGIONS || 'us-east5,us-east1,europe-west1').split(','),
7
+ geminiLocation: process.env.GEMINI_LOCATION || 'us-east5',
8
+ port: parseInt(process.env.PORT || '8001'),
9
+ host: process.env.HOST || '0.0.0.0',
10
+ maxRetries: parseInt(process.env.MAX_RETRIES || '3'),
11
+ retryBaseDelay: parseFloat(process.env.RETRY_BASE_DELAY || '0.5'),
12
+ requestTimeout: parseInt(process.env.REQUEST_TIMEOUT || '300'),
13
+ enablePromptCache: process.env.ENABLE_PROMPT_CACHE !== 'false',
14
+ enableMetrics: process.env.ENABLE_METRICS !== 'false',
15
+ enableRequestLogging: process.env.ENABLE_REQUEST_LOGGING === 'true',
16
+ heartbeatInterval: parseInt(process.env.HEARTBEAT_INTERVAL || '15'),
17
+ maxConcurrent: parseInt(process.env.MAX_CONCURRENT || '10'),
18
+ queueSize: parseInt(process.env.QUEUE_SIZE || '100'),
19
+ };
20
+ exports.CLAUDE_MODELS = {
21
+ 'opus': 'claude-opus-4-5@20251101',
22
+ 'sonnet': 'claude-sonnet-4-5@20250929',
23
+ 'haiku': 'claude-haiku-3-5@20241022',
24
+ 'claude-opus-4-5': 'claude-opus-4-5@20251101',
25
+ 'claude-sonnet-4-5': 'claude-sonnet-4-5@20250929',
26
+ };
27
+ exports.GEMINI_MODELS = {
28
+ 'gemini-3-pro': 'gemini-3-pro-preview',
29
+ 'gemini-2.5-pro': 'gemini-2.5-pro',
30
+ 'gemini-2.5-flash': 'gemini-2.5-flash',
31
+ 'gemini-2.0-flash': 'gemini-2.0-flash',
32
+ };
33
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AA4Ea,QAAA,cAAc,GAAgB;IACzC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,EAAE;IAC3E,aAAa,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,gCAAgC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;IAC1F,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,UAAU;IACzD,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC;IAC1C,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,SAAS;IACnC,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC;IACpD,cAAc,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,KAAK,CAAC;IACjE,cAAc,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,KAAK,CAAC;IAC9D,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,OAAO;IAC9D,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,OAAO;IACrD,oBAAoB,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,KAAK,MAAM;IACnE,iBAAiB,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,IAAI,CAAC;IACnE,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC;IAC3D,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,KAAK,CAAC;CACrD,CAAC;AAEW,QAAA,aAAa,GAA2B;IACnD,MAAM,EAAE,0BAA0B;IAClC,QAAQ,EAAE,4BAA4B;IACtC,OAAO,EAAE,2BAA2B;IACpC,iBAAiB,EAAE,0BAA0B;IAC7C,mBAAmB,EAAE,4BAA4B;CAClD,CAAC;AAEW,QAAA,aAAa,GAA2B;IACnD,cAAc,EAAE,sBAAsB;IACtC,gBAAgB,EAAE,gBAAgB;IAClC,kBAAkB,EAAE,kBAAkB;IACtC,kBAAkB,EAAE,kBAAkB;CACvC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "vertex-ai-proxy",
3
+ "version": "1.0.0",
4
+ "description": "OpenAI-compatible proxy for Google Vertex AI (Claude + Gemini) with automatic failover, retries, and prompt caching",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "vertex-ai-proxy": "dist/cli.js",
9
+ "vap": "dist/cli.js"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "start": "node dist/cli.js",
14
+ "dev": "ts-node src/cli.ts",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "keywords": [
18
+ "vertex-ai",
19
+ "claude",
20
+ "gemini",
21
+ "openai",
22
+ "proxy",
23
+ "anthropic",
24
+ "google-cloud",
25
+ "clawdbot",
26
+ "ai",
27
+ "llm"
28
+ ],
29
+ "author": "ramonqu",
30
+ "license": "MIT",
31
+ "dependencies": {
32
+ "@anthropic-ai/vertex-sdk": "^0.6.4",
33
+ "@google/genai": "^1.0.0",
34
+ "express": "^4.18.2",
35
+ "prom-client": "^15.1.0"
36
+ },
37
+ "devDependencies": {
38
+ "@types/express": "^4.17.21",
39
+ "@types/node": "^20.10.0",
40
+ "typescript": "^5.3.0"
41
+ },
42
+ "engines": {
43
+ "node": ">=18"
44
+ },
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "https://github.com/anthropics/vertex-ai-proxy"
48
+ },
49
+ "files": [
50
+ "dist",
51
+ "README.md"
52
+ ]
53
+ }